I\'m implementing CORS with credentials and a preflight request and I\'m a bit mystified why the preflight request consistently fails in Firefox 30 but works in Safari (7.0.
Note that Firefox is the only browser that is compliant here. If parsing of Access-Control-Allow-Methods
fails per https://fetch.spec.whatwg.org/#cors-preflight-fetch a network error needs to be returned. And per the ABNF for the header value it is most definitely a comma-separated value.
I have noticed that when you a send CORS(Cross Origin Resource Sharing) request with cookies set, Firefox doesn't send the required response headers.
Solution:
Below solution adds headers only for OPTIONS requests and accepts requests only from example.com. You can change the implementation for other request methods and expected hosts.
JS CODE
var xmlhttp = new XMLHttpRequest();
xmlhttp.withCredentials = true;
xmlhttp.onreadystatechange = function () {
if (xmlhttp.readyState == XMLHttpRequest.DONE) {
if (xmlhttp.status == 200) {
success_callback(xmlhttp.responseText);
} else {
error_callback(xmlhttp.statusText);
}
}
};
xmlhttp.open("DELETE", url);
xmlhttp.send(null);
When you send a DELETE request, the browser send a pre-flight request for OPTIONS, which expects Access-Control-Allow-Methods in the response headers. Based on this header value the actual DELETE request is sent. In Firefox, when you send a DELETE request the pre-flight request's response headers do not have expected headers, therefore it fails to send the actual DELETE request.
To overcome this problem use the below NGINX server config.
NGINX CODE
#handle CORS requests by adding required headers
if ($http_origin ~* .example.com) {
set $cors "CORS-${request_method}";
}
if ($cors = "CORS-OPTIONS") {
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Allow-Headers' 'Content-Type';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, DELETE';
add_header 'Access-Control-Allow-Origin' $http_origin;
}
Good read on CORS: https://www.html5rocks.com/en/tutorials/cors/