Home > Software engineering >  React PHP API throws CORS preflight error
React PHP API throws CORS preflight error

Time:12-28

I am trying to call a PHP API running on localhost:8000 from a React app running on localhost:3000. After many tries I am still getting "CORS Preflight Did Not Succeed" error.

Sent from the React app: Sent from the app

Sent from the devtools: Sent from the devtools

My API has following headers:

if (@$_SERVER['HTTP_ORIGIN']) {
  header("Origin: http://localhost:8000");
  header("Access-Control-Allow-Origin: *");
  header('Access-Control-Allow-Methods: GET, POST, OPTIONS');
  header('Access-Control-Max-Age: 1000');
  header('Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept');
} 

I call the API with fetch like this (but it somehow sends empty request body):

let inputData:object = {email, password}
fetch("http://localhost:8000/data/login", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
  },
  body: JSON.stringify(inputData)
})
.then(response => {
  console.log(response)
})
.catch(error => {
  console.log(error)
})

The strange thing is that the requests are working normally when sent directly from the browser devtools (2nd screenshot) or API clients like Insomnia:

Sent from an API client

CodePudding user response:

Your cors origin must be localhost:3000.

header("Origin: http://localhost:3000");

Because your frontend running on 3000.

Where the request comes from should be added as cors definition.

CodePudding user response:

Make sure you are not outputting anything in php before returning the response to the frontend application. A simple echo "test"; or a print_r, vardump etc. can trigger this error.

Also, make sure there are no empty lines before the opening <?php tags since they send a premature response to the frontend that may cause this error.

CodePudding user response:

Problem(s)

Your first screenshot indicates that the response to the preflight request has status code 404. However, a necessary condition for CORS preflight to succeed is an ok status (i.e. a status in the range 2xx). See the relevant section (3.2.3) of the Fetch standard:

A successful HTTP response, i.e., one where the server developer intends to share it, to a CORS request can use any status, as long as it includes the headers stated above with values matching up with the request.

A successful HTTP response to a CORS-preflight request is similar, except it is restricted to an ok status, e.g., 200 or 204.

(my emphasis)

Solution

Make sure your server responds with a 2xx status to preflight requests that are meant to succeed.


Additional remarks

  • There is never a need to allow the Origin header, since it's set by the user agent. You can remove Origin from the value of the Access-Control-Allow-Headers response header.
  • Why you're setting an Origin header in the response is unclear... Origin is a request header. You should be able to drop that header("Origin: http://localhost:8000"); line.
  • Related