【问题标题】:React + PHP API throws CORS preflight errorReact + PHP API 引发 CORS 预检错误
【发布时间】:2022-01-26 13:28:43
【问题描述】:

我正在尝试从在 localhost:3000 上运行的 React 应用调用在 localhost:8000 上运行的 PHP API。经过多次尝试后,我仍然收到“CORS Preflight Did Not Succeed”错误。

从 React 应用发送:

从开发工具发送:

我的 API 有以下标头:

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(但它以某种方式发送空请求正文):

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)
})

奇怪的是,当直接从浏览器开发工具(第二张截图)或 Insomnia 等 API 客户端发送请求时,这些请求可以正常工作:

【问题讨论】:

  • Access-Control-Allow-Headers:* 有帮助吗?
  • @nice_dev 不幸的是,我得到了同样的错误。
  • 好的,如答案中所述,服务器必须以 200 ok 状态响应 OPTIONS 请求。

标签: php reactjs api cors fetch


【解决方案1】:

问题

您的第一个屏幕截图表明对预检请求的响应具有状态代码 404。但是,CORS 预检成功的必要条件是 ok status(即 2xx 范围内的状态)。见relevant section (3.2.3) of the Fetch standard

对 CORS 请求的成功 HTTP 响应(即服务器开发人员打算共享它的响应)可以使用任何状态,只要它包含上述标头以及与请求匹配的值。

对 CORS 预检请求的成功 HTTP 响应与此类似,除了 它被限制为 ok 状态,例如 200 或 204

(我的重点)

解决方案

确保您的服务器以 2xx 状态响应旨在成功的预检请求。


补充说明

  1. 永远不需要允许Origin 标头,因为它是由用户代理设置的。您可以从 Access-Control-Allow-Headers 响应标头的值中删除 Origin
  2. 您在响应中设置Origin 标头的原因尚不清楚...Origin is a request header。您应该可以删除 header("Origin: http://localhost:8000"); 行。
  3. 您应该考虑使用经过验证的 CORS 中间件,而不是“手动”实施 CORS(这很容易出错)。

【讨论】:

  • 是的,这帮我解决了!非常感谢。问题是如果$_SERVER['REQUEST_METHOD'] != "POST",我会返回 404 请求。
  • @DanielNýdrle 很好,但考虑使用可靠的 CORS 中间件,而不是手动设置 CORS 标头。你会省去一些麻烦!
【解决方案2】:

您的 cors 来源必须是 localhost:3000。

header("来源:http://localhost:3000");

因为您的前端在 3000 上运行。

请求的来源应添加为 cors 定义。

【讨论】:

  • 还是一样的结果,可惜...
【解决方案3】:

在将响应返回给前端应用程序之前,请确保您没有在 php 中输出任何内容。简单的echo "test";print_rvardump 等都可能触发此错误。

另外,请确保在打开 <?php 标记之前没有空行,因为它们会向前端发送可能导致此错误的过早响应。

【讨论】:

    猜你喜欢
    • 2016-08-21
    • 2021-11-09
    • 2015-02-04
    • 2020-05-04
    • 2019-04-11
    • 1970-01-01
    • 2017-08-01
    • 2021-01-14
    • 2021-11-14
    相关资源
    最近更新 更多