React + PHP API 抛出 CORS 预检错误
React + PHP API throws CORS preflight error
我正在尝试从 localhost:3000
上的 React 应用 运行 在 localhost:8000
上调用 PHP API 运行。经过多次尝试后,我仍然收到“CORS 预检未成功”错误。
从 React 应用发送:
从开发工具发送:
我的 API 有以下 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');
}
我用这样的 fetch 调用 API(但它以某种方式发送空请求 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)
})
奇怪的是,直接从浏览器开发工具(第二张截图)或 API Insomnia 等客户端发送请求时,请求工作正常:
你的 cors 来源必须是 localhost:3000。
header("来源:http://localhost:3000");
因为您的前端 运行 在 3000 上。
应将请求的来源添加为 cors 定义。
问题
您的第一个屏幕截图表明对预检请求的响应具有状态代码 404。但是,CORS 预检成功的必要条件是 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.
(我的重点)
解决方案
确保您的服务器以 2xx 状态响应本应成功的预检请求。
补充说明
- 从来没有必要允许
Origin
header,因为它是由用户代理设置的。您可以从 Access-Control-Allow-Headers
响应 header. 的值中删除 Origin
- 为什么要在 响应 中设置
Origin
header 不清楚... Origin
is a request header。您应该能够删除 header("Origin: http://localhost:8000");
行。
- 您应该考虑使用经过验证的 CORS 中间件,而不是“手动”实施 CORS(error-prone)。
在将响应返回给前端应用程序之前,请确保您没有在 php
中输出任何内容。一个简单的 echo "test";
或 print_r
、vardump
等可以触发此错误。
此外,请确保在开始 <?php
标记之前没有空行,因为它们会向前端发送过早的响应,这可能会导致此错误。
我正在尝试从 localhost:3000
上的 React 应用 运行 在 localhost:8000
上调用 PHP API 运行。经过多次尝试后,我仍然收到“CORS 预检未成功”错误。
从 React 应用发送:
从开发工具发送:
我的 API 有以下 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');
}
我用这样的 fetch 调用 API(但它以某种方式发送空请求 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)
})
奇怪的是,直接从浏览器开发工具(第二张截图)或 API Insomnia 等客户端发送请求时,请求工作正常:
你的 cors 来源必须是 localhost:3000。
header("来源:http://localhost:3000");
因为您的前端 运行 在 3000 上。
应将请求的来源添加为 cors 定义。
问题
您的第一个屏幕截图表明对预检请求的响应具有状态代码 404。但是,CORS 预检成功的必要条件是 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.
(我的重点)
解决方案
确保您的服务器以 2xx 状态响应本应成功的预检请求。
补充说明
- 从来没有必要允许
Origin
header,因为它是由用户代理设置的。您可以从Access-Control-Allow-Headers
响应 header. 的值中删除 - 为什么要在 响应 中设置
Origin
header 不清楚...Origin
is a request header。您应该能够删除header("Origin: http://localhost:8000");
行。 - 您应该考虑使用经过验证的 CORS 中间件,而不是“手动”实施 CORS(error-prone)。
Origin
在将响应返回给前端应用程序之前,请确保您没有在 php
中输出任何内容。一个简单的 echo "test";
或 print_r
、vardump
等可以触发此错误。
此外,请确保在开始 <?php
标记之前没有空行,因为它们会向前端发送过早的响应,这可能会导致此错误。