React.js + PHP/Apache:预检响应中的 Access-Control-Allow-Headers 不允许请求标头字段内容类型

Posted

技术标签:

【中文标题】React.js + PHP/Apache:预检响应中的 Access-Control-Allow-Headers 不允许请求标头字段内容类型【英文标题】:React.js + PHP/Apache: Request header field content-type is not allowed by Access-Control-Allow-Headers in preflight response 【发布时间】:2020-04-29 09:33:03 【问题描述】:

我想在 React.js 中创建一个联系页面。单击提交按钮后,使用 fetch 方法(使用 POST)调用 php 页面(在 Apache 上)。不幸的是,我不断收到以下错误(在我的 localhost:3000/dev 机器和 Apache 服务器上:

Access to fetch at 'http://example.com/dir/email.php' from origin 'http://localhost:3000' has been blocked by CORS policy: Request header field content-type is not allowed by Access-Control-Allow-Headers in preflight response.

这是提交时调用的sendEmail 函数:

  sendEmail() 
    fetch('http://example.com/dir/email.php', 
      method: 'POST',
      headers: 
        Accept: 'application/json',
        'Content-Type': 'application/json',
      ,
      body: JSON.stringify(
        'firstname': this.state.firstName,
        'lastname': this.state.lastName,
        'message': this.state.message
      )
    ).then(function(response) 
      console.log(response);
      return response.json();
    ).then(function (json) 
      console.log(json);
    );
  

我的 PHP 脚本现在看起来像这样(我现在没有任何逻辑):

<?php
  header('Access-Control-Allow-Origin: *');
  header('Access-Control-Allow-Methods: GET, POST');
  header("Access-Control-Allow-Headers: X-Requested-With");

  echo json_encode(array('success' => true));

我也尝试添加一个 .htaccess 文件,其内容如下,但这似乎也不起作用:

<IfModule mod_headers.c>
    Header set Access-Control-Allow-Origin "*"
    Header set Access-Control-Content-Type "*"
    Header set Access-Control-Accept "*"
    Header set Access-Control-Allow-Methods "GET, POST"
    Header set Access-Control-Allow-Headers: X-Custom-Header
</IfModule>

我认为问题应该出在服务器上,因为我在fetch 上找到的所有示例看起来都像我的。我搜索了这个问题,但我找到的答案不起作用或者是针对 Express 服务器的。

也许还有其他更好的方法可以在 React.js 中创建像这样的简单联系表单,所以我愿意接受建议。我对 React.js 很陌生,所以我很有可能遗漏了一些明显的东西......

非常感谢您的任何意见!

【问题讨论】:

错误说 Request header field content-type is not allowed 你用 header("Access-Control-Allow -Headers: X-Requested-With");Header 设置 Access-Control-Allow-Headers: X-Custom-Header! — 您必须允许您发送的标头而不是随机的不同标头!! 【参考方案1】:

在发出 CORS 请求(即域名与 html 的域不同的 AJAX/JSON/HTTP 请求)之前,浏览器将发送一个带有 OPTIONS 方法的“飞行前请求”。

参考:https://developer.mozilla.org/en-US/docs/Glossary/Preflight_request

所以,把它放在你的 php 文件中:

<?php
// CORS support
header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Headers: *");

// https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS
if($_SERVER["REQUEST_METHOD"] == "OPTIONS") exit();
// before sending CORS request, modern browsers often make "pre-flight request" in order to see which headers are allowed/accepted from custom origin
// that request must be answered with status code 200 OK, and must contain header Acces-Control-Allow-Headers

解释:

预检请求旨在确保服务器理解该请求是 CORS 请求。 “Access-Control-Allow-Header”列出了可用于后续 CORS 请求的所有 HTTP 标头

更详细的解释可以在上面的参考链接中阅读

【讨论】:

感谢您的回复。我在我的 PHP 脚本中尝试了上面的代码,但现在我得到了:Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled. @Sabrina 更改您的 .htaccess 以允许 OPTIONS 方法。例如:Header set Access-Control-Allow-Methods "GET, POST, OPTIONS"。基本上,不要将允许的方法限制为 GET 和 POST,因为它会拒绝预检请求 有效!将OPTIONS 添加到 .htaccess 文件就可以了。不过,我不得不从我的 PHP 文件中删除行 header("Access-Control-Allow-Origin: *");。首先,我收到一个错误,即不允许多个来源(*,*)。我猜我的 .htaccess 中的一个和我的 PHP 文件中的一个正在合并。非常感谢!

以上是关于React.js + PHP/Apache:预检响应中的 Access-Control-Allow-Headers 不允许请求标头字段内容类型的主要内容,如果未能解决你的问题,请参考以下文章

使用 Spring Boot 和 Zuul 进行 CORS 预检请求的 Host vs Origin 标头

React.js 应用程序没有“Access-Control-Allow-Origin”标头

用户“root”的访问被拒绝。 PHP/MYSQL/XAMPP

从源 xxxx 访问 XMLHttpRequest ' 被 CORS 策略阻止:对预检的响应。预检请求不允许重定向

如何解决“预检无效(重定向)”或“预检请求不允许重定向”

如何解决“预检无效(重定向)”或“预检请求不允许重定向”