Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CORS post with preflight request

I'm trying to upload files to a service on a different domain using CORS, but they keep failing due to the origin being denied. As far as I can see the correct headers are being used to allow this.

Javascript request:

  var xhr = new XMLHttpRequest();
  xhr.open('POST', "https://files.example.com", true);                                                                                                                            
  xhr.setRequestHeader('Content-Type', 'application/json');
  xhr.onreadystatechange = function () {
    if (this.status == 200 && this.readyState == 4) {
      console.log('response: ' + this.responseText);
    }
  };

  xhr.send();

Response from the preflight OPTIONS request:

Access-Control-Allow-Headers:Origin, Authorization, Content-Type
Access-Control-Allow-Methods:POST, OPTIONS
Access-Control-Allow-Origin:*
Content-Length:0
Content-Type:application/json
Date:Mon, 19 Nov 2012 23:30:21 GMT

Headers for POST request:

Cache-Control:no-cache
Content-Type:application/json
Origin:https://www.example.com
Pragma:no-cache
Referer:https://www.example.com
User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_0) AppleWebKit/537.19 (KHTML, like     Gecko) Chrome/25.0.1325.0 Safari/537.19

Which results in the error:

XMLHttpRequest cannot load https://files.example.com. Origin https://www.example.com is not allowed by Access-Control-Allow-Origin.
like image 950
rlayte Avatar asked Nov 20 '12 00:11

rlayte


People also ask

Does post require preflight?

GET , POST , and HEAD are considered simple requests (and are case-sensitive). They do not require preflight. The simple headers that do not require preflight are as follows: Cache-control.

Does CORS apply to post?

Any CORS request has to be preflighted if: Also, if POST is used to send request data with a Content-Type other than application/x-www-form-urlencoded, multipart/form-data, or text/plain, e.g. if the POST request sends an XML payload to the server using application/xml or text/xml, then the request is preflighted.

How does a CORS preflight work?

CORS also relies on a mechanism by which browsers make a "preflight" request to the server hosting the cross-origin resource, in order to check that the server will permit the actual request. In that preflight, the browser sends headers that indicate the HTTP method and headers that will be used in the actual request.

How do I identify CORS preflight request?

Check for the existence of these essential information present in a preflight request: The request's HTTP method is OPTIONS. It has an Origin header. It has an Access-Control-Request-Method header, indicating what's the actual method it's trying to use to consume your service/resource.


1 Answers

Unfortunately, POSTing to a domain other than your page's elicits CORS. That also includes different subdomains, ports and protocol (http/https).

Preflight is done when the request is "not simple", meaning, a content-type header set to something other than "text/plain". Your "application/json" makes browsers get scared into preflighting.

If those 50-200 ms are important to you, then you can rewrite your web service to understand the "simple" content type. If not, then you should make your web service throw back HTTP status 204 (no content) when it is tasked with OPTIONS (http method).

When dealing with a wcf:

WebOperationContext.Current.OutgoingResponse.StatusCode = System.Net.HttpStatusCode.NoContent;
like image 166
Oooogi Avatar answered Sep 27 '22 21:09

Oooogi