如何配置 IIS,以便在 HTML5模式下重写 AngularJS 应用程序?

我有 AngularJS 种子项目,我已经添加了

$locationProvider.html5Mode(true).hashPrefix('!');

我想配置 IIS 7将所有请求路由到

http://localhost/app/index.html

这样我就可以工作了,我该怎么做?

更新:

我刚刚发现,下载和安装的 重写模块,希望这将使它容易和明显地实现我的目标。

更新2 :

我想这就是我想要达到的目标(摘自 AngularJS 开发人员文档) :

使用此模式需要在服务器端重写 URL, 基本上你必须重写你所有的链接到你的入口点 应用程序(例如 index.html)

更新3:

我仍然在这方面的工作,我意识到我需要不重定向(有规则,重写)某些网址,如

http://localhost/app/lib/angular/angular.js
http://localhost/app/partials/partial1.html

所以任何在 css、 js、 lib 或 partals 目录中的内容都不会被重定向。其他所有内容都需要重定向到 app/index.html

有人知道如何轻松实现这一点,而不必为每个文件添加规则吗?

更新4:

我在 IIS URL Rewrite 模块中定义了2个入站规则:

IIS URL Rewrite Inbound Rule 1

第二条规则是:

IIS URL Rewrite Inbound Rule 2

现在,当我导航到 localhost/app/view1时,它会加载页面,但是支持文件(css、 js、 lib 和 partals 目录中的文件)也会被重写到 app/index.html 页面中——所以不管使用什么 URL,所有东西都会返回 index.html 页面。我想这意味着我的第一条规则,即防止这些 URL 被第二条规则处理的规则,不起作用了。.有什么想法吗?有人知道吗?我感到很孤独

147814 次浏览

问题 DO 中显示的 IIS 入站规则可以工作。我必须清除浏览器缓存,并在 index.html 页面的 <head>部分的顶部添加以下代码行:

<base href="/myApplication/app/" />

这是因为我在 localhost 中有不止一个应用程序,所以对其他部分的请求被发送到 localhost/app/view1而不是 localhost/myApplication/app/view1

希望这能帮到别人!

在我的例子中,在设置了正确的重写规则之后,我不断得到一个403.14。原来,我有一个与我的一个 URL 路由同名的目录。删除 IsDirectory 重写规则后,我的路由工作正常。是否存在删除目录否定可能导致问题的情况?我想不出来。我能想到的唯一情况是你能用你的应用程序浏览一个目录。

<rule name="fixhtml5mode" stopProcessing="true">
<match url=".*"/>
<conditions logicalGrouping="MatchAll">
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
</conditions>
<action type="Rewrite" url="/" />
</rule>

app.js中设置 $locationProvider.html5Mode(true)之后,我在 web.config 中写出一条规则。

Hope 帮助别人。

  <system.webServer>
<rewrite>
<rules>
<rule name="AngularJS Routes" 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>
</rules>
</rewrite>
</system.webServer>

在 index.html 中,我将其添加到 <head>

<base href="/">

别忘了在服务器上安装 重写

另外,如果您使用 Web API 和 IIS,那么如果由于第三个输入(条件的第三行) ,您的 API 位于 www.yourdomain.com/api,那么这将是有效的。

只有这两个条件的问题:

  <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />

它们的工作时间只有 {REQUEST_FILENAME} 物理存在于磁盘上。这意味着,在某些情况下,对命名不正确的部分视图的请求会返回根页面,而不是404页面,这会导致角度加载两次(在某些情况下,它会导致讨厌的无限循环)。

因此,建议制定一些安全的“备用”规则,以避免这些难以解决的问题:

  <add input="{REQUEST_FILENAME}" pattern="(.*?)\.html$" negate="true" />
<add input="{REQUEST_FILENAME}" pattern="(.*?)\.js$" negate="true" />
<add input="{REQUEST_FILENAME}" pattern="(.*?)\.css$" negate="true" />

匹配任何文件结尾:

<conditions>
<!-- ... -->
<add input="{REQUEST_FILENAME}" pattern=".*\.[\d\w]+$" negate="true" />
</conditions>

我发现最简单的方法就是将触发404的请求重定向到客户机。即使设置了 $locationProvider.html5Mode(true),也可以通过添加标签来实现。

此技巧适用于同一 Web 站点上具有更多 Web 应用程序且需要 URL 完整性约束(例如,外部身份验证)的环境。下面是一步一步该怎么做

Html

正确设置 <base>元素

<base href="@(Request.ApplicationPath + "/")">

Web.config

首先将404重定向到自定义页面,例如“ Home/Error”

<system.web>
<customErrors mode="On">
<error statusCode="404" redirect="~/Home/Error" />
</customErrors>
</system.web>

主控制器

实现一个简单的 ActionResult来“翻译”客户端路由中的输入。

public ActionResult Error(string aspxerrorpath) {
return this.Redirect("~/#/" + aspxerrorpath);
}

这是最简单的方法。


这是可能的(明智的?)用一些改进的逻辑来增强 Error 函数,只有当 url 有效时才将404重定向到客户端,当客户端上没有任何东西时才让404正常触发。 假设你有这些角度路线

.when("/", {
templateUrl: "Base/Home",
controller: "controllerHome"
})
.when("/New", {
templateUrl: "Base/New",
controller: "controllerNew"
})
.when("/Show/:title", {
templateUrl: "Base/Show",
controller: "controllerShow"
})

只有当 URL 以“/New”或“/Show/”开头时,将 URL 重定向到客户端才有意义

public ActionResult Error(string aspxerrorpath) {
// get clientside route path
string clientPath = aspxerrorpath.Substring(Request.ApplicationPath.Length);


// create a set of valid clientside path
string[] validPaths = { "/New", "/Show/" };


// check if clientPath is valid and redirect properly
foreach (string validPath in validPaths) {
if (clientPath.StartsWith(validPath)) {
return this.Redirect("~/#/" + clientPath);
}
}


return new HttpNotFoundResult();
}

这只是一个改进逻辑的例子,当然每个 Web 应用程序都有不同的需求

我一直在尝试将一个简单的 Angular 7应用程序部署到一个 Azure Web 应用程序中。 一切正常,直到您刷新了页面。这样做,就是向我提供了500个错误移动的内容。 我在 Angular 文档和一些论坛上都读到过,我需要在部署的解决方案中添加一个 web.config 文件,并确保重写规则回退到 index.html 文件。 经过几个小时的挫折和试错测试,我发现这个错误非常简单: 在我的文件标记周围添加一个标记。

我也遇到过类似的问题,Angular 和 IIS 在手动刷新时抛出了一个404状态代码,并尝试了投票最多的解决方案,但这对我来说不起作用。还尝试了许多其他解决方案,必须处理 WebDAV 和更改处理程序,但没有一个奏效。

幸运的是,我发现 这个解决方案和它的工作(删除部分,我不需要)。因此,如果上述方法都不适用于您,甚至在尝试它们之前,请尝试这个方法,看看它是否能修复您在 iis 问题上的角度部署。

将代码段添加到站点根目录中的 webconfig 中。根据我的理解,它从任何继承(applicationhost.config,machine.config)中删除404状态代码,然后在站点级别创建一个404状态代码,并以自定义404页面的形式重定向回主页。

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<httpErrors errorMode="Custom">
<remove statusCode="404"/>
<error statusCode="404" path="/index.html" responseMode="ExecuteURL"/>
</httpErrors>
</system.webServer>
</configuration>

不幸的是,最好的解决方案不适合我使用。NET 框架4.5和 IIS 6.2。我得到它的工作,首先按照所有的步骤来安装从微软的 URL 重写工具,然后调整我的 Web.config文件,包括以下内容:

    <system.webServer>
<!-- handlers etc -->
<rewrite>
<rules>
<rule name="Angular Routes" stopProcessing="true">
<match url="(^(?!.*\.[\d\w]+$).*)" />
<conditions logicalGrouping="MatchAny">
<add input="{REQUEST_URI}" pattern=".*\/api\/.*" negate="true" />
</conditions>
<action type="Rewrite" url="./index.html" />
</rule>
</rules>
</rewrite>
</system.webServer>

第一个正则表达式使用负向前查找来不匹配 URI 末尾的任何文件扩展名。然后,在条件中,包括 /api/在内的任何 URI 也被忽略。

这个配置允许我刷新 Angular 应用程序而不会中断路由,也可以访问我的 API 而不需要重写。