UI Router template/html requests throws 406 error code

15 Jul 2016

Recently I tried using Angular UI router in one of my pet projects and found a strange issue. The IIS throws 406 error code - 406 Not Acceptable Response  for all XHR/Ajax requests that are made by the UI router. Then I started validating things that were done different for this website setup, to identify what is not acceptable for ASP.Net website.

  1. AngularJS ajax calls are getting executed as expected, where as Angular UI requests were blocked
  2. The project was using ASP.Net MVC boilerplate template, which comes with predefined set of best practices and security setup in Web.Config

While checking the XHR calls made by Angular UI router, I found that the the Request Headers were missing charset in the headers.

Header sent by Angular UI Router

Content-Type "text/html"

Header sent by Angular JS

Content-Type text/html; charset=UTF-8

This doesn't look like a major issue at first, because mentioning a Charset was never a mandate for any requests. Then I went through my web.config, which exactly showed me what caused this extra validation.

<!-- .html - Add the optional charset to the HTML MIME type. -->
<remove fileExtension=".html" />
<mimeMap fileExtension=".html" mimeType="text/html; charset=UTF-8" />

This above mimeType mappings has added the charset=UTF-8 to the HTML responses and it also caused IIS to verify & reject the requests(406) without the proper headers from the client.

Then I went through the issues logged in Angular UI router - GitHub and found an issue raised related to this topic (https://github.com/angular-ui/ui-router/issues/1610). There seems to be no idea for Angular UI router devs. / community to add those extra headers.

So in order to fix the issue, I added an interceptor for all HttpRequest made by Angular and set a proper Content-Type for all .html request to avoid any such issues as shown below

app.config(["$httpProvider",
 function($httpProvider) {
   $httpProvider.interceptors.push(function() {
     return {
       "request": function(config) {
         if (config.url && config.url.endsWith(".html")){
           config.headers["Content-Type"] = "text/html; charset=utf-8";
           config.headers["Accept"] = "text/html; charset=utf-8";
         }
         return config;
       }
     };
   });
 };

Hope this helps.