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

后端 未结 7 2090
春和景丽
春和景丽 2020-11-22 12:12

I have the AngularJS seed project and I\'ve added

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

to the app.js file. I want to confi

相关标签:
7条回答
  • 2020-11-22 12:15

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

    0 讨论(0)
  • 2020-11-22 12:24

    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>
    
    0 讨论(0)
  • 2020-11-22 12:25

    The IIS inbound rules as shown in the question DO work. I had to clear the browser cache and add the following line in the top of my <head> section of the index.html page:

    <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

    Hopefully this helps someone!

    0 讨论(0)
  • 2020-11-22 12:26

    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

    0 讨论(0)
  • 2020-11-22 12:30

    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>
    
    0 讨论(0)
  • 2020-11-22 12:33

    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.

    0 讨论(0)
提交回复
热议问题