Why is this CORS request failing only in Firefox?

后端 未结 2 1080
无人及你
无人及你 2020-12-15 17:18

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.

相关标签:
2条回答
  • 2020-12-15 17:40

    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.

    0 讨论(0)
  • 2020-12-15 17:41

    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/

    0 讨论(0)
提交回复
热议问题