147

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

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

到 app.js 文件。我想将 IIS 7 配置为将所有请求路由到

http://localhost/app/index.html

所以这对我有用。我该怎么做呢?

更新:

我刚刚发现、下载并安装了IIS URL Rewrite 模块,希望这将使实现我的目标变得容易和明显。

更新 2

我想这总结了我想要实现的目标(取自AngularJS Developer 文档):

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

更新 3:

我仍在努力,我意识到我不需要重定向(有重写的规则)某些 URL,例如

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

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

任何人都知道如何轻松实现这一点而无需为每个文件添加规则?

更新 4:

我在 IIS URL 重写模块中定义了 2 个入站规则。第一条规则是:

IIS URL 重写入站规则 1

第二条规则是:

IIS URL 重写入站规则 2

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

4

8 回答 8

303

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

希望,帮助某人。

  <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="/">

不要忘记在服务器上安装IIS URL Rewrite

此外,如果您使用 Web API 和 IIS,如果您的 APIwww.yourdomain.com/api由于第三个输入(第三行条件)而位于,这将起作用。

于 2014-10-01T22:57:40.467 回答
40

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

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

这是因为我在 localhost 中有多个应用程序,因此对其他部分的请求被带到localhost/app/view1而不是localhost/myApplication/app/view1

希望这可以帮助某人!

于 2012-10-25T00:09:47.990 回答
13

只有这两个条件的问题:

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

是它们仅{REQUEST_FILENAME} 在磁盘上物理存在时才起作用。这意味着在某些情况下,对错误命名的局部视图的请求将返回根页面而不是 404,这会导致 Angular 被加载两次(在某些情况下,它可能会导致令人讨厌的无限循环)。

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

  <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>
于 2015-11-25T20:13:33.940 回答
11

就我而言,在设置正确的重写规则后,我一直得到 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>
于 2014-07-23T21:51:45.270 回答
3

我遇到了 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>
于 2019-12-05T14:57:03.230 回答
1

我发现最简单的方法就是将触发 404 的请求重定向到客户端。这是通过添加主题标签来完成的,即使$locationProvider.html5Mode(true)已设置。

这个技巧适用于在同一个网站上有更多 Web 应用程序并需要 URL 完整性约束(例如外部身份验证)的环境。这是一步一步的方法

索引.html

正确设置<base>元素

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

网络配置

首先将 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);
}

这是最简单的方法。


可以(建议?)通过一些改进的逻辑来增强错误功能,仅当 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 应用程序都有不同的需求

于 2016-06-30T12:34:20.283 回答
1

不幸的是,使用 .NET 框架 4.5 和 IIS 6.2 的最佳解决方案对我不起作用。我首先按照从 Microsoft安装URL Rewrite 工具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 末尾的任何文件扩展名。然后,在条件内部,任何包含在内的 URI/api/也将被忽略。

此配置允许我在不中断路由的情况下刷新 Angular 应用程序,并且还可以在不重写的情况下访问我的 API。

于 2022-02-02T02:28:42.830 回答
0

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

于 2019-02-16T20:47:35.747 回答