简体   繁体   English

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

[英]How do I configure IIS for URL Rewriting an AngularJS application in HTML5 mode?

I have the AngularJS seed project<\/a> and I've added我有AngularJS 种子项目<\/a>,我已经添加了

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

I write out a rule in web.config after $locationProvider.html5Mode(true) is set in app.js .app.js设置$locationProvider.html5Mode(true)后,我在 web.config 中写出一条规则。

Hope, helps someone out.希望,能帮到人。

  <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>

In my index.html I added this to <head>在我的 index.html 中,我将其添加到<head>

<base href="/">

Don't forget to install IIS URL Rewrite on server.不要忘记在服务器上安装IIS URL Rewrite

Also if you use Web API and IIS, this will work if your API is at www.yourdomain.com/api because of the third input (third line of condition).此外,如果您使用 Web API 和 IIS,由于第三个输入(条件的第三行),如果您的 API 位于www.yourdomain.com/api ,这将起作用。

The IIS inbound rules as shown in the question DO work.问题中显示的 IIS 入站规则有效。 I had to clear the browser cache and add the following line in the top of my <head> section of the index.html page:我必须清除浏览器缓存并在 index.html 页面的<head>部分的顶部添加以下行:

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

This is because I have more than one application in localhost and so requests to other partials were being taken to localhost/app/view1 instead of localhost/myApplication/app/view1这是因为我在 localhost 中有多个应用程序,因此对其他部分的请求被带到localhost/app/view1而不是localhost/myApplication/app/view1

Hopefully this helps someone!希望这对某人有所帮助!

The issue with only having these two conditions:只有这两个条件的问题:

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

is that they work only as long as the {REQUEST_FILENAME} exists physically on disk .是它们仅在{REQUEST_FILENAME} 物理存在于磁盘上时才起作用。 This means that there can be scenarios where a request for an incorrectly named partial view would return the root page instead of a 404 which would cause angular to be loaded twice (and in certain scenarios it can cause a nasty infinite loop).这意味着在某些情况下,对错误命名的部分视图的请求将返回根页面而不是 404,这会导致 angular 加载两次(并且在某些情况下可能会导致令人讨厌的无限循环)。

Thus, some safe "fallback" rules would be recommended to avoid these hard to troubleshoot issues:因此,建议使用一些安全的“后备”规则来避免这些难以解决的问题:

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

or a condition that matches any file ending :匹配任何文件结尾的条件:

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

In my case I kept getting a 403.14 after I had setup the correct rewrite rules.就我而言,在设置正确的重写规则后,我一直收到 403.14。 It turns out that I had a directory that was the same name as one of my URL routes.事实证明,我有一个与我的 URL 路由之一同名的目录。 Once I removed the IsDirectory rewrite rule my routes worked correctly.一旦我删除了 IsDirectory 重写规则,我的路由就可以正常工作。 Is there a case where removing the directory negation may cause problems?是否存在删除目录否定可能会导致问题的情况? I can't think of any in my case.我想不出我的情况。 The only case I can think of is if you can browse a directory with your app.我能想到的唯一情况是您是否可以使用您的应用浏览目录。

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

I had a similar issue with Angular and IIS throwing a 404 status code on manual refresh and tried the most voted solution but that did not work for me.我有一个类似的问题,Angular 和 IIS 在手动刷新时抛出 404 状态代码,并尝试了投票最多的解决方案,但这对我不起作用。 Also tried a bunch of other solutions having to deal with WebDAV and changing handlers and none worked.还尝试了许多其他必须处理 WebDAV 和更改处理程序的解决方案,但都没有奏效。

Luckily I found this solution and it worked (took out parts I didn't need).幸运的是我找到了这个解决方案并且它起作用了(取出了我不需要的部分)。 So if none of the above works for you or even before trying them, try this and see if that fixes your angular deployment on iis issue.因此,如果上述方法都不适合您,甚至在尝试之前,请尝试此操作,看看是否可以解决您在 iis 问题上的角度部署问题。

Add the snippet to your webconfig in the root directory of your site.将代码片段添加到站点根目录中的 webconfig。 From my understanding, it removes the 404 status code from any inheritance (applicationhost.config, machine.config), then creates a 404 status code at the site level and redirects back to the home page as a custom 404 page.根据我的理解,它从任何继承(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>

The easiest way I found is just to redirect the requests that trigger 404 to the client.我发现的最简单的方法就是将触发 404 的请求重定向到客户端。 This is done by adding an hashtag even when $locationProvider.html5Mode(true) is set.即使设置了$locationProvider.html5Mode(true)也可以通过添加主题标签来完成此操作。

This trick works for environments with more Web Application on the same Web Site and requiring URL integrity constraints (EG external authentication).此技巧适用于在同一网站上具有更多 Web 应用程序并需要 URL 完整性约束(EG 外部身份验证)的环境。 Here is step by step how to do这是一步一步的操作方法

index.html索引.html

Set the <base> element properly正确设置<base>元素

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

web.config网页配置

First redirect 404 to a custom page, for example "Home/Error"首先将 404 重定向到自定义页面,例如“主页/错误”

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

Home controller家庭控制器

Implement a simple ActionResult to "translate" input in a clientside route.实现一个简单的ActionResult来“翻译”客户端路由中的输入。

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

This is the simplest way.这是最简单的方法。


It is possible (advisable?) to enhance the Error function with some improved logic to redirect 404 to client only when url is valid and let the 404 trigger normally when nothing will be found on client.可以(建议?)使用一些改进的逻辑来增强错误功能,以便仅在 url 有效时将 404 重定向到客户端,并在客户端上找不到任何内容时让 404 正常触发。 Let's say you have these angular routes假设您有这些角度路线

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

It makes sense to redirect URL to client only when it start with "/New" or "/Show/"仅当 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();
}

This is just an example of improved logic, of course every web application has different needs这只是改进逻辑的一个例子,当然每个Web应用程序都有不同的需求

I've been trying to deploy a simple Angular 7 application, to an Azure Web App.我一直在尝试将一个简单的 Angular 7 应用程序部署到 Azure Web 应用程序。 Everything worked fine, until the point where you refreshed the page.一切正常,直到您刷新页面为止。 Doing so, was presenting me with an 500 error - moved content.这样做,向我展示了 500 错误 - 移动了内容。 I've read both on the Angular docs and in around a good few forums, that I need to add a web.config file to my deployed solution and make sure the rewrite rule fallback to the index.html file.我已经阅读了 Angular 文档和一些论坛,我需要将 web.config 文件添加到我部署的解决方案中,并确保重写规则回退到 index.html 文件。 After hours of frustration and trial and error tests, I've found the error was quite simple: adding a tag around my file markup.经过数小时的挫折和反复试验,我发现错误很简单:在我的文件标记周围添加一个标签。

The top solution for this unfortunately did not work for me using .NET framework 4.5 and IIS 6.2.不幸的是,使用 .NET 框架 4.5 和 IIS 6.2 的最佳解决方案对我不起作用。 I got it to work by first following all the steps to install the URL Rewrite tool<\/a> from Microsoft, then adjusting my Web.config<\/code> file to include the following:我首先按照从 Microsoft 安装URL Rewrite 工具<\/a>的所有步骤操作,然后调整我的Web.config<\/code>文件以包含以下内容:

    <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>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM