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 the error:
"CORS Preflight Did Not Succeed"
Sent from the React app:
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:
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)
Make sure your server responds with a 2xx status to preflight requests that are meant to succeed.
Origin
header is never necessary, simply because it's set by the user agent. You can drop Origin
from the value of the Access-Control-Allow-Headers
response header.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.