Why CORS gives different response at different con

2019-02-28 22:13发布

问题:

When making a call to the server of the third party domain without a request content type, I get a CORS error and no response. But when making a call with a content type text/plain (which is the the true content-type of the response) then I get a response but with a CORS error so I am unable to parse that to the dom. The question is why is the response coming the second time and not the first time. Both are still a CORS error. How can I parse the error the second time since I am getting a response from the server?

   <!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <script>
        var xhr = new XMLHttpRequest();
        xhr.open('GET', 'http://www.w3schools.com/xml/ajax_info.txt', true);
        xhr.setRequestHeader('content-type', undefined);
        xhr.onload = function () {
            console.log('Test');
        };
        xhr.send(null);
        var contentXHR = new XMLHttpRequest();
        contentXHR.open('GET', 'http://www.w3schools.com/xml/ajax_info.txt', true);
        contentXHR.setRequestHeader('content-type', 'text/plain');
        contentXHR.onload = function () {
            console.log('Test request header');
        };
        contentXHR.send(null);
    </script>
  </head>
    <body>
            Check console and network tab
    </body>
</html>

回答1:

When you don't specify Content-type, XHR executes a CORS preflight request. Note that your request is OPTIONS, and not GET. That's why you don't get any response from the network tab.

According to CORS specification:

A header is said to be a simple header if the header field name is an ASCII case-insensitive match for Accept, Accept-Language, or Content-Language or if it is an ASCII case-insensitive match for Content-Type and the header field value media type (excluding parameters) is an ASCII case-insensitive match for application/x-www-form-urlencoded, multipart/form-data, or text/plain.

(...)

It gets slightly more complicated if the resource author wants to be able to handle cross-origin requests using methods other than simple methods. In that case the author needs to reply to a preflight request that uses the OPTIONS method and then needs to handle the actual request that uses the desired method (DELETE in this example) and give an appropriate response.

So, in summary, if your Content-Type is different than application/x-www-form-urlencoded, multipart/form-data, or text/plain, XHR will trigger the preflight (send a OPTIONS http verb).