403: Cursed by CORS

Ronny Roeller
NEXT Engineering
Published in
1 min readFeb 10, 2016

We replaced our XMLHttpRequest’s with the awesome Fetch API (for detail see Jake’s blog post). Along the way, we ran into a sneaky CORS issue.

Trimming down

That’s a simplified version of our old code (imagine the full version to be “XMLHttpRequest mess” at it’s best):

var request = new XMLHttpRequest();
request.onreadystatechange = function() {
// Finished?
if (request.readyState === 4) {
// Successful?
if (request.status === 200) onSuccess();
}
};
request.open('POST', url, true);
request.setRequestHeader('Content-Type', application/json');
request.send();

With the Fetch API this snippet becomes very pleasant to read:

fetch(url, { method: 'POST' }).then(function(response) {
if (response.ok) return onSuccess();
});

Looks good. Well, minor detail: it doesn’t work. Every request results in a 403 Forbidden response. Yikes!

Content-Type matters

So, going on here? During the refactoring, we removed the Content-Type entry from the HTTP header because we don’t send any payload anyway. Unfortunately, CORS filters don’t like this but required the Content-Type to be always set to one of the white-listed values.

Once brought back, all requests work again like a charm:

fetch(url, {
method: 'POST',
headers: { 'Content-Type': 'application/json' }
}).then(function(response) {
if (response.ok) return onSuccess();
});

Happy coding!

Photo: Matt

--

--

Ronny Roeller
NEXT Engineering

CTO at nextapp.co # Product discovery platform for high performing teams that bring their customers into every decision