如何在HTML5模式下为URL重写AngularJS应用程序配置IIS?

时间:2012-09-27 04:24:43

标签: iis url-rewriting angularjs

我有AngularJS seed project而我已添加

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

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

http://localhost/app/index.html

这样对我有用。我该怎么做?

更新

我刚刚发现,下载并安装了IIS URL Rewrite module,希望这样可以轻松明了地实现我的目标。

更新2

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

  

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

更新3:

我还在努力解决这个问题,我意识到我不需要重定向(有重写规则)某些网址,例如

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

所以css,js,lib或partials目录中的任何内容都不会被重定向。其他所有内容都需要重定向到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和partials目录中的文件)也会被重写到app / index.html页面 - 所以无论使用什么URL,一切都会以index.html页面的形式返回。我想这意味着我的第一条规则,即应该阻止这些网址被第二条规则处理,不起作用......任何想法? ...任何人? ......我感到很孤单......: - (

7 个答案:

答案 0 :(得分:267)

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

希望,帮助别人。

  <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,如果您的API位于www.yourdomain.com/api,由于第三个输入(第三行条件),这将起作用。

答案 1 :(得分:36)

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

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

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

希望这有助于某人!

答案 2 :(得分:9)

在我的情况下,在设置了正确的重写规则后,我一直得到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>

答案 3 :(得分:9)

只有这两个条件的问题:

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

只有{REQUEST_FILENAME} exists physically on disk才有效。这意味着可能存在这样的情况:对错误命名的局部视图的请求将返回根页而不是404将导致角加载两次(并且在某些情况下它可能导致令人讨厌的无限循环)。

因此,一些安全&#34;后退&#34;建议使用规则以避免这些难以解决的问题:

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

matches any file ending

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

答案 4 :(得分:1)

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

此技巧适用于在同一网站上具有更多Web应用程序并且需要URL完整性约束的环境(E.G。外部身份验证)。这是一步一步如何做的

的index.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"
})

只有在以“/ 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应用程序都有不同的需求

答案 5 :(得分:1)

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

幸运的是,我发现了this solution并且它起作用了(取出了我不需要的部分)。因此,如果上述方法都不适合您,甚至在尝试使用它们之前,都可以尝试一下,看看是否能解决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>

答案 6 :(得分:0)

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