34
votes

On making request like that:

return fetch(
            'http://localhost:8000/login',
            {   method: 'POST',
                headers: new Headers(
                   {"Content-Type": "application/json",
                    "Accept":"application/json"}
                ),

                body: JSON.stringify(
                   {'name': 'Tom', 'password': 'Soyer'}
                )
             }
           ).then( response => { console.log(response);})
            .catch(err => console.log(err))

request running with method OPTIONS instead POST. Only on adding mode: 'no-cors' request become POST:

return fetch(
            'http://localhost:8000/login',
            {   method: 'POST',
                mode: 'no-cors',
                headers: new Headers(
                   {"Content-Type": "application/json",
                    "Accept":"application/json"}
                ),
                body: JSON.stringify(
                   {'name': 'Tom', 'password': 'Soyer'}
                )
             }
           ).then( response => { console.log(response);})
            .catch(err => console.log(err))

but response not ok than (even if network response status is 200): {type: "opaque", url: "", status: 0, ok: false, statusText: ""…} I suppose it because

The only allowed values for the Content-Type header are: application/x-www-form-urlencoded multipart/form-data text/plain

described here https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS

Is any way bring to live POST json data with fetch?

3
Well, just a) don't make cross-domain http requests or b) answer them with the appropriate CORS headersBergi
have you solved your issue..if yes, can you updated your answer..PvDev

3 Answers

42
votes

The custom Content-Type header you're sending causes your request to be preflighted, which means an OPTIONS request, containing some metadata about the POST request that is about to be dispatched, will be sent before the actual POST request.

Your server needs to be prepared to deal with this OPTIONS request. You haven't specified what the server is written in, but with express for example, you can register a middleware that intercepts all 'OPTIONS' requests, sets the Access-Control-Allow-Origin: * and Access-Control-Allow-Headers: Content-Type headers, and responds with 200.

If it is possible for you to make the request using a 'Content-Type': 'text/plain' header, that would solve your problem. Alternatively you could use something that bypasses XHR entirely, like JSONP.

9
votes

When using non-cors, all headers must be valid simple-headers. The only valid values for the content-type header that qualifies as a simple-header is:

headers: [
  ['Content-Type', 'application/x-www-form-urlencoded'],
  ['Content-Type', 'multipart/form-data'],
  ['Content-Type', 'text/plain'],
]

Exceptions with contingencies:

headers: [
  ['Content-Type', 'application/csp-report'],
  ['Content-Type', 'application/expect-ct-report+json'],
  ['Content-Type', 'application/xss-auditor-report'],
  ['Content-Type', 'application/ocsp-request'],
]
0
votes

If you are trying to call an api and getting stuck with this in your react app you can add a proxy to the server and the cors error will get removed

just add this line at the package.json

"proxy":"url-to-your-server",