在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=""c:\program files\nodejs\node.exe"" watchedFiles="*.js"
interceptor=""%programfiles%\iisnode\interceptor.js"" 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的主要内容,如果未能解决你的问题,请参考以下文章