4

I have an angular 2 app with a simple server.js as a node.js BE.

I have deployed my application to Azure and I'm at the point that the application loads and shows me the welcoming page.

When I reach a component that tries to read a local JSON via an HTTP request I'm getting a 404 error (that I don't receive in my local environment). enter image description here

The code to read the json is the following:

private ReadFromJson(path: string): Observable<string[]> {
    return this._http.get(path)
        .map((response: Response) => <string[]>response.json())
        .do(data => console.log('All: ' + JSON.stringify(data)))
        .catch(this.handleError);
}

where the actual path passed is the one showed in the console.

I have done two things: First I made sure that the file is actually there using the Azure CLI, and it is there as expected.

Secondly, after viewing many posts the only other solution I found was to add the MIME type as suggested here, but that didn't work for me as well.

I would really like some help in understanding and be troubleshooting the problem, any suggestion is welcomed!

Aaron Chen
  • 9,835
  • 1
  • 16
  • 28
Belgi
  • 14,542
  • 22
  • 58
  • 68

3 Answers3

9

Update:

If your app is just front-end (Angular) app, then you no longer need to serve these static files via Node.js. Because by default Azure App Service have installed IIS on it and IIS can serve any file type by doing some configuration. So, in this case, you can just keep web.config looking like below and put it to "site/wwwroot/dist".

<?xml version="1.0" encoding="UTF-8" ?>
<configuration>
    <system.webServer>
        <staticContent>
            <remove fileExtension=".json" />
            <mimeMap fileExtension=".json" mimeType="application/json" />
        </staticContent>
    </system.webServer>
</configuration>

As you deployed a Node.js on Azure App Service, which would host your app using iisnode, and you probably have a web.config file that looks like the content in this link.

By default, this configuration file assumes the static file in the /public folder.

<!-- First we consider whether the incoming URL matches a physical file in the /public folder -->
<rule name="StaticContent">
    <action type="Rewrite" url="public{REQUEST_URI}" />
</rule>

So, after you add this to web.config,

<staticContent>
    <remove fileExtension=".json" />
    <mimeMap fileExtension=".json" mimeType="application/json" />
</staticContent>

please make sure the static files were put into /public file.

enter image description here

enter image description here

Aaron Chen
  • 9,835
  • 1
  • 16
  • 28
  • Thanks for the answer! I suspect this is the root cause. My web.config looks like yours (with both the highlighted sections) . My root folder is configured in Azure to "site\wwwroot\dist". Inside my root folder I have opened a folder named "public" and I have copied all files to that location. I have also made sure to deploy this folder to the "dist" folder when I'm building angular. However when I try to access my site in a similar way as you did I am getting an error ("The resource you are looking for has been removed, had its name changed, or is temporarily unavailable."). – Belgi Jun 27 '17 at 16:27
  • I have tried both http://soundofsilence.azurewebsites.net/Images.json and http://soundofsilence.azurewebsites.net/public/Images.json. I think that this may be related to the application root defined, what do you think ? – Belgi Jun 27 '17 at 16:29
  • How did you set up static directory `/assets/images`? You should do the same thing for `/public`. – Aaron Chen Jun 28 '17 at 05:53
  • I haven't set anything do define that folder in any way.. The only thing that I have done is to deploy that folder into the dist folder, which is done when I build angular and that needed to be configured explicitly. I also had the public folder deployed to my dist folder as well. – Belgi Jun 28 '17 at 16:50
  • Something interesting to isolate the problem: I copied one of the png files into the same folder the json is in, I can navigate (in the browser) to the png url and access it (the images displays on the screen), but when I access the json I get an error. This means that the problem isn't with the folder not being public, but something specific to the json file being json – Belgi Jun 28 '17 at 17:08
  • Well, since you've configured "site\wwwroot\dist" as root folder, you'd need to put the `web.config` to "site\wwwroot\dist" rather than "site\wwwroot" . – Aaron Chen Jun 29 '17 at 02:31
  • I have deployed the web.config file to the dist folder, but still no luck.. – Belgi Jun 29 '17 at 09:36
4

I ran into the same problem last week and thought maybe i should share my findings since i got it to work as desired.

I deployed the app developed using angular cli and built using the same. I copied over all files in the /dist folder over to azure and added a web.config (this was a lot of hit and trial) but i learned that a rewrite rule for angular was required which can process the webpack bundled assets and not return a 404.

Here is the web,config and i believe it should work for you as-is:

<?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|.svg|.eot|.woff|\​.woff2)).*$" />
          <conditions logicalGrouping="MatchAll"></conditions>
          <action type="Rewrite" url="/" appendQueryString="true" />
        </rule>
      </rules>
    </rewrite>
    <staticContent>
      <remove fileExtension=".svg" />
      <remove fileExtension=".eot" />
      <remove fileExtension=".woff" />
      <remove fileExtension=".woff2" />
      <mimeMap fileExtension=".svg" mimeType="image/svg+xml" />
      <mimeMap fileExtension=".eot" mimeType="application/vnd.ms-fontobject" />
      <mimeMap fileExtension=".woff" mimeType="application/font-woff" />
      <mimeMap fileExtension=".woff2" mimeType="application/font-woff" />
    </staticContent>
  </system.webServer>
</configuration>
<!--

This is required for the app to work in Azure or an ASP.NET hosting environment because the woff files 
are not treated as static content on Azure as well as the routing breaks without the rewrite rule below 
and app or rather the server returns a 404.

-->
Digvijay
  • 774
  • 5
  • 10
  • Thanks! It'll try this out. Did you have a problem with a .json file as well? I noticed that you don't have a mime map for it as well – Belgi Jul 05 '17 at 16:56
  • No, i did not face any issues since i had no json files to serve. However if you do just add and in the above file. – Digvijay Jul 05 '17 at 21:42
  • and since you have a different folder serving files i guess you may need to set the correct rewrite path in the rule e.g. url="/dist" etc – Digvijay Jul 05 '17 at 21:51
  • @Belgi - did you get to try it – Digvijay Jul 06 '17 at 07:50
  • I have added the json mime type and the removed part, I have also edited the url to be /dist as you suggested, but there is still the same error unfortunately – Belgi Jul 06 '17 at 16:12
0

Below suggestion worked wonders.

If your app is just front-end (Angular) app, then you no longer need to serve these static files via Node.js. Because by default Azure App Service have installed IIS on it and IIS can serve any file type by doing some configuration. So, in this case, you can just keep web.config looking like below and put it to "site/wwwroot/dist".

Adding web.config worked

Thanks for excellent solution.