在AngularJS中使用Node for Angular HTML5 Mode重写IIS URL

Posted

技术标签:

【中文标题】在AngularJS中使用Node for Angular HTML5 Mode重写IIS URL【英文标题】:IIS URL Rewrite in AngularJS with Node for Angular HTML5 Mode 【发布时间】:2015-12-08 09:34:20 【问题描述】:

我有一个基于 Node.JS 构建的 AngularJS 应用程序,它托管在 Azure (IIS) 中并使用 html5 模式。在我不使用 Node.JS 而只使用 AngularJS 和 IIS 的情况下,我可以使用 IIS Web.config 中的以下规则重写 URL,以便页面刷新不会导致 404 错误:

<rule name="AngularJSHTML5Mode" stopProcessing="true">
      <match url=".*"/>
      <conditions logicalGrouping="MatchAll">
        <add input="REQUEST_FILENAME" matchType="IsFile" negate="true"/>
        <add input="REQUEST_FILENAME" matchType="IsDirectory" negate="true"/>
        <add input="REQUEST_URI" pattern="^/(api)" negate="true"/>
      </conditions>
      <action type="Rewrite" url="/"/>
</rule>

但是,当在 Node.js 之上使用 Angular(使用 ExpressJS)时,即使在 IIS 中使用上述规则,我也会在页面刷新时收到诸如“Cannot GET /myroute”之类的错误。我需要在 Server.js 中配置什么或在 Web.config 中配置不同的规则。

这是我目前在 Express 中的内容。我正在使用 Express 4:

// Initialize Express App
var app = express();

var listener = app.listen(1337, function () 
    console.log('Listening on port ' + listener.address().port); //Listening on port 1337
);

app.use(express.static(__dirname + "/public"));

我知道在实践中不应该在 SPA 中进行页面刷新,但确实如此,我需要考虑到这一点。

【问题讨论】:

不,你必须在 node.js 中配置它。一旦请求被移交给 node.js,web.config 什么也不做。 你有如何做到这一点的例子吗? 我没有,但它通常只是一个简单的 app.get( 中间件,它会跟踪您的路由并呈现 index.html 而不是给出 404。 【参考方案1】:

我已经尝试过,这对我有用:

web.config(site.js 是我的节点应用程序的入口点)

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <system.webServer>
        <httpErrors existingResponse="PassThrough" />

        <iisnode nodeProcessCommandLine="&quot;c:\program files\nodejs\node.exe&quot;" watchedFiles="*.js" 
      interceptor="&quot;%programfiles%\iisnode\interceptor.js&quot;" promoteServerVars="LOGON_USER"/>
        <handlers>
            <add name="iisnode" path="site.js" verb="*" modules="iisnode" />
        </handlers>

        <rewrite>
            <rules>
                <clear />
                <rule name="default">
                    <match url="/*" />
                    <conditions logicalGrouping="MatchAll" trackAllCaptures="false" />
                    <action type="Rewrite" url="site.js" />
                </rule>
            </rules>
        </rewrite>

        <security>
            <requestFiltering>
                <hiddenSegments>
                    <add segment="node_modules" />
                </hiddenSegments>
            </requestFiltering>
        </security>
    </system.webServer>
</configuration>

express 中的静态文件服务器 + url 重写

app.use(express.static(clientDir));

// for SPA
app.get('/*', function(req,res, next)
    res.format(
        html: function()
            res.sendFile(path.join(clientDir, 'index.html'));
        ,
        json: function()
            next();
        
    );
);

//routes...

我还尝试在 iis 中使用虚拟应用程序实现 url 重写。这行不通。相反,我必须在我的节点模块中配置一个路径来剥离路径的前导部分。

但是,一旦您的应用启动后,您就可以拥有iis serve the static files。

【讨论】:

我试过这个,但它对我不起作用。我正在使用 Express 4,并将在我的原始帖子中发布适当的代码。 @Kode 这绝对适合我。我这里有一个例子:github.com/futurechan/how-to-node/tree/master/leveraging-gulp 它不包含 web.config,但我可以通过 iisnode 将它部署到 iis 并包含上面的 web.config,它可以工作。 谢谢,我刚刚通过另一种方法让它工作了。现在发布答案。【参考方案2】:

进一步挖掘后,我不需要 Web 配置。我在 server.js 中有这个来建立与 Angular 索引文件的连接:

var app = express();

app.use(express.static(__dirname + "/public"));


var listener = app.listen(1337, function () 
    console.log('Listening on port ' + listener.address().port); //Listening on port 1337
);

这部分很关键,在所有 GET、POST 等的末尾。我将其添加为最后一个函数。它需要放在最后,因为它是一个包罗万象的,如果你把它放在一个 GET 或 POST 函数之前,它不会将它视为 Express,而是一个损坏的 Angular 路由,如果你的 App.js 配置正确,将路由到主页(不需要):

// Placed at end for routing non-Express calls/AngularJS refreshes
app.use('/*', function (req, res) 
    res.sendFile(__dirname + '/public/index.html');
);

【讨论】:

它实际上不需要放在最后。您可以利用内容协商。 text/html 的请求将转到静态文件,如果未找到匹配项,则提供 index.html。 application/json 的请求可以去路由,不管顺序。

以上是关于在AngularJS中使用Node for Angular HTML5 Mode重写IIS URL的主要内容,如果未能解决你的问题,请参考以下文章

AngularJS:http服务

在 AngularJS 中使用逗号作为列表分隔符

AngularJS-选择框Select

AngularJs:重新加载页面

使用 AngularJS 服务代替 KendoUI 调度程序中的 url

AngularJS 四 服务