7

I'm developing an app in Angular 2 using the angular cli. The app works fine, and runs ok when I deploy it in Azure, but the routing doesn't work. I can access my app via "myapp.azurewebsites.net", but if I try "myapp.azurewebsites.net/settings" I get an 404 error. I have found a lot of guides with a lot of different ways to make different servers route everything to one index-file, but none have worked, at all. Like providing an web.config file, configuring node or express server, and both at the same time.

So, my question consists of two parts.
1. What kind of web app template in Azure is best suited for hosting an Angular2 application?
It's just a single page application written in Angular2. Not the kind that is wrapped in an ASP.NET MVC application.

2. How do I configure that web app to use the routing I have configured in Angular

Community
  • 1
  • 1
Kristoffer Berge
  • 1,046
  • 1
  • 20
  • 36
  • Windows Azure Websites run IIS.You can use rewrite module within `web.config` to move all unknown urls to `index.html` or `/` http://stackoverflow.com/questions/12614072/how-do-i-configure-iis-for-url-rewriting-an-angularjs-application-in-html5-mode – yurzui Mar 14 '17 at 12:42
  • Yes, I have tried adding a web.config that looks exactly like that, but it doesn't seem to do anything. I linked to a similar solution in my question. – Kristoffer Berge Mar 14 '17 at 13:52

1 Answers1

13
  1. What kind of web app template in Azure is best suited for hosting an Angular2 application?

We've been hosting our ng2 sites on Azure in a standard Azure "Web App" template as it is just a basic IIS site template that can be used to serve static resources. (No node or express solutions used.) From what you explained, this should be sufficient.

  1. How do I configure that web app to use the routing I have configured in Angular?

As part of the deployment, this Web.Config is FTP'd to the sites' root directory (/site/wwwroot -- where the index.html is located) with the rest of the build artifacts:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <system.webServer>
    <rewrite>
      <rules>
        <rule name="AngularJS" stopProcessing="true">
          <match url="^(?!.*(.bundle.js|.bundle.map|.bundle.js.gz|.bundle.css|.bundle.css.gz|.png|.jpg|.ico)).*$" />
          <conditions logicalGrouping="MatchAll">
          </conditions>
          <action type="Rewrite" url="/"  appendQueryString="true" />
        </rule>
      </rules>
    </rewrite>
  </system.webServer>
</configuration>

This basically uses a RegEx to route all requests back to index.html (or root, if you prefer), except for the static resources that I'm using (.js, .css, .png, etc.)

Same caveats apply from my original answer.

Update: Long URLs/OAuth

Upon applying the suggested changes to the web.config, Kristoffer (The OP) encountered an issue with this OAuth solution where the OAuth return query string length exceeded Azure's default allowed length and was still returning the following 400 error:

The length of the query string for this request exceeds the configured maxQueryStringLength value.

Kristoffer was able to increase the request limit using the solution provided in this StackOverflow answer by adding <requestLimits maxQueryString="32768"/> and <httpRuntime maxQueryStringLength="32768" maxUrlLength="65536"/> to the web.config. His updated web.config can be found in the Gist "Configuration file for Azure web app to support angular2 applications with routing and long urls for auth tokens.", and is provided below for completeness.

<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <system.web>
        <httpRuntime maxQueryStringLength="32768" maxUrlLength="65536"/>
    </system.web>
    <system.webServer>
        <security>
            <requestFiltering>
                <requestLimits maxQueryString="32768"/>
            </requestFiltering>
        </security>
        <rewrite>
            <rules>
                <rule name="AngularJS" stopProcessing="true">
                    <match url="^(?!.*(.bundle.js|.bundle.map|.bundle.js.gz|.bundle.css|.bundle.css.gz|.png|.jpg|.ico)).*$" />
                    <conditions logicalGrouping="MatchAll"></conditions>
                    <action type="Rewrite" url="/" appendQueryString="true" />
                </rule>
            </rules>
        </rewrite>
    </system.webServer>
</configuration>
Community
  • 1
  • 1
Steve
  • 11,596
  • 7
  • 39
  • 53
  • This almost works! I have a problem where the code I receive in the OAuth flow is too long for the IIS server. If the url is longer than 2095 characters I get the same 404 error that i did before. This makes it impossible to use OAuth... – Kristoffer Berge Mar 14 '17 at 20:43
  • @KristofferBerge Have you tried increasing your request limit to support the OAuth URL param length? Just spit-balling. – Steve Mar 14 '17 at 20:56
  • Been trying to find out how to do that for a while. Can't seem to see to find an option for that in the azure portal and setting the requestlimits in the web.config file gives an internal server error. http://stackoverflow.com/questions/2840885/500-error-for-long-url-iis7 – Kristoffer Berge Mar 14 '17 at 21:07
  • 1
    Both requestLimits and httpRuntime elements had to be configured for the server to handle longer urls. I edited your answer to include this. It's finally working! Thanks :) – Kristoffer Berge Mar 14 '17 at 23:12
  • Well, my edit was rejected. Hope you will add the requestilimit and httpruntime elements to the xml in your answer. – Kristoffer Berge Mar 15 '17 at 09:10
  • 1
    @KristofferBerge will do! Can you paste just the relevant lines that you added for requestLimit and httpRuntime into a comment, and I'll add them to the answer. – Steve Mar 15 '17 at 13:19
  • 2
    I created a gist for the config file here: https://gist.github.com/KristofferBerge/cf3dfd61405359403bd3839be9ceb9e9 Found the solution in this answer: http://stackoverflow.com/a/11636484/5119447 – Kristoffer Berge Mar 15 '17 at 13:24
  • 1
    @KristofferBerge The answer has been updated with your findings. Good luck with your app! – Steve Mar 15 '17 at 13:48
  • 1
    If you are using angular with webpack you also want to add .chunk.js to your rewrite regex. Otherwise the generated chunk files cannot be loaded ;) – pbo May 09 '17 at 09:21
  • Using that web.config, I got ride of 404 but my fontawesome icons are not found anymore. – François Dec 12 '17 at 16:24
  • 1
    @François: You'll need to add to the `` element's regular expression, any other files that are hosted on your site that you just want to "pass through". For example, `|.eot|.svg|.ttf|.woff|.woff2` for font files. This is one of the down sides of handling it this way. – Steve Dec 12 '17 at 16:28
  • This answer assumes the app is the only thing being served by the host. If you have other items like an api, you'll need to exclude them, or simply match (route1|route2|route3) for the re-write. – kevinc Nov 17 '18 at 12:11