We’re all familiar with basic authentication (or should be) – my experience with it has been via cPanel or doing it by hand on *nix servers. Once setup it just works. The other day I was integrating an app into a service where the dev environment had basic authentication on it. My AJAX calls were blocked (naturally) but did not trigger a username/password dialog to appear. I had assumed that the browser would just “do its thing”.

What is happening behind the scenes is that my AJAX call causes the server to return a 401 HTML error page. This is an unexpected response that jQuery can’t handle and that will cause the following error in the console:

$ Uncaught SyntaxError: Unexpected token < in JSON at position 0 at JSON.parse ()

jQuery will also return a status code “0” which, by the way, is a generic error from jQuery. As the response from the server was an HTML document (401 error page) jQuery couldn’t parse it (it was expecting the response to be JSON) thus the above error. Lacking any proper status code to use jQuery then just uses “0”.

Lastly if I inspect the response header I can see that WWW-Authenticate: Basic appears. That’s a clue as to what we should do to get things working which is to add a Authorization:Basic header to our AJAX request to begin with.

We can add the necessary header by specifying the beforeSend callback when we configure the AJAX request. Inside of the callback we can create the Authorization header that will be added to our request. See the following example:

  $.ajax(
    {
      method: 'POST',
      contentType: 'application/json',
      url: 'service URL here'
      data:'data here',
      beforeSend: function (xhr) {
        xhr.setRequestHeader ('Authorization', 'Basic xxxx');
      },
    })
    .done(function( data, textStatus, jqXHR ) {
      // do something here...
    })
    .fail(function( jqXHR, textStatus, errMsg ){
      // do something here...
    });

Here you can see that we are setting the “Authorization” header via xhr.setRequestHeader. The spec says that Basic should be followed by a base-64 representation of the user name and password to authenticate with but in this case we are using an arbitrary string. Since its obviously wrong the server will respond by asking for the correct credentials; the authentication dialog will appear.

As you can see there is some interaction going back and forth between the client and the server. If you’re attentive to the network tab in the Chrome console you can see the handshaking as it happens.