The trick to getting XHR requests to work with Elm or Javascript when developing with Safari

My development of my latest Elm app came crashing to a halt when suddenly pages that had been working fine started returning 401 Unauthorised HTTP errors.

I was writing a Single Page Application (SPA) that was using XHR (Ajax) requests to retrieve information from an existing Rail web site. The SPA was served up from a local test server whilst the API was served from a different host. The behaviour seemed to have no pattern, sometimes the requests went through fine, sometimes the dreaded 401 error.

Inspecting the network requests in the developer console, the problem was obvious – sometimes the requests were sending the session cookie, and sometimes not. I could make the app fail every time by deleting the cookies associated with the API web site. Once I had done this, I couldn’t log in. However, if I opened the API web site in a different tab, and logged in (and even out), my SPA app would now send the session cookie and work fine.

The problem was my privacy settings in Safari. I had chosen Allow from Websites I visit. From the documentation:

Allow from Websites I Visit – Allow all first-party cookies and block all third-party cookies unless that third party was a first party at one time (based on current cookies and browsing history).

The issue came down to the trust being based on my previous browsing activity. Simply visiting the API website in my browser was enough to flag the cookie as a first-party cookie. The SPA then could send the cookie. If that site visit wasn’t in my history (and this seems to be recorded along with the cookie in the cookie store), Safari wouldn’t send the cookie to the third party API website.

So, if you’re developing a Javascript application that uses XHR and testing in Safari, check your Cookie privacy settings, or make a manual visit the API server to enable the cookies to be sent by your application.

Leave a Reply

Your email address will not be published. Required fields are marked *