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

0qx6xfy6  于 2023-04-19  发布在  Angular
关注(0)|答案(8)|浏览(110)

我有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)。

    • 更新三:**

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

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

所以css、js、lib或partials目录中的任何内容都不会被重定向。其他内容需要重定向到app/index.html
有人知道如何轻松实现这一点,而不必为每个文件添加规则吗?

    • 更新4:**

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

第二条规则是:

现在,当我导航到localhost/app/view1时,它会加载页面,但是支持文件(css,js,lib和partials目录中的)也被重写到app/index.html页面-所以无论使用什么URL,所有内容都将返回index.html页面。我猜这意味着我的第一条规则,即应该防止这些URL被第二条规则处理,我不知道我在做什么,我觉得我很孤独:()

dgiusagp

dgiusagp1#

I write out a rule in web.config after $locationProvider.html5Mode(true) is set in app.js .
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>

<base href="/">

Don't forget to install IIS URL Rewrite on server.
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).

u5i3ibmn

u5i3ibmn2#

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

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

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

rjjhvcjd

rjjhvcjd3#

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 . 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).
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>
4xrmg8kj

4xrmg8kj4#

In my case I kept getting a 403.14 after I had setup the correct rewrite rules. It turns out that I had a directory that was the same name as one of my URL routes. Once I removed the IsDirectory rewrite rule my routes worked correctly. 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>
e5njpo68

e5njpo685#

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. Also tried a bunch of other solutions having to deal with WebDAV and changing handlers and none worked.
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.
Add the snippet to your webconfig in the root directory of your site. 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.

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

vcudknz36#

不幸的是,我使用.NET Framework 4.5和IIS 6.2时,最好的解决方案不起作用。我首先按照所有步骤从Microsoft安装URL Rewrite tool,然后调整我的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。

brccelvz

brccelvz7#

The easiest way I found is just to redirect the requests that trigger 404 to the client. This is done by adding an hashtag even when $locationProvider.html5Mode(true) is set.
This trick works for environments with more Web Application on the same Web Site and requiring URL integrity constraints (E.G. external authentication). Here is step by step how to do

index.html

Set the <base> element properly

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

web.config

First redirect 404 to a custom page, for example "Home/Error"

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

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

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

lndjwyie

lndjwyie8#

I've been trying to deploy a simple Angular 7 application, to an Azure Web App. Everything worked fine, until the point where you refreshed the page. Doing so, was presenting me with an 500 error - moved content. 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. After hours of frustration and trial and error tests, I've found the error was quite simple: adding a tag around my file markup.

相关问题