我有一个简单的 PHP 脚本,我正在尝试跨域 CORS 请求:
<?php
header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Headers: *");
...
但我仍然收到错误:
X-Requested-With
不允许Access-Control-Allow-Headers
请求标头字段
我还缺少什么吗?
正确处理 CORS 请求有点复杂。这是一个可以更全面(且正确)响应的函数。
/**
* An example CORS-compliant method. It will allow any GET, POST, or OPTIONS requests from any
* origin.
*
* In a production environment, you probably want to be more restrictive, but this gives you
* the general idea of what is involved. For the nitty-gritty low-down, read:
*
* - https://developer.mozilla.org/en/HTTP_access_control
* - https://fetch.spec.whatwg.org/#http-cors-protocol
*
*/
function cors() {
// Allow from any origin
if (isset($_SERVER['HTTP_ORIGIN'])) {
// Decide if the origin in $_SERVER['HTTP_ORIGIN'] is one
// you want to allow, and if so:
header("Access-Control-Allow-Origin: {$_SERVER['HTTP_ORIGIN']}");
header('Access-Control-Allow-Credentials: true');
header('Access-Control-Max-Age: 86400'); // cache for 1 day
}
// Access-Control headers are received during OPTIONS requests
if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_METHOD']))
// may also be using PUT, PATCH, HEAD etc
header("Access-Control-Allow-Methods: GET, POST, OPTIONS");
if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']))
header("Access-Control-Allow-Headers: {$_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']}");
exit(0);
}
echo "You have CORS!";
}
根据批准的来源列表检查 HTTP_ORIGIN 标头。
如果来源未获批准,那么您应该拒绝该请求。
请阅读规格。
当浏览器想要执行跨站点请求时,它首先确认对 URL 的“飞行前”请求是否可以。通过允许 CORS,您将告诉浏览器来自此 URL 的响应可以与其他域共享。
CORS 不保护您的服务器。 CORS 尝试通过告诉浏览器与其他域共享响应的限制来保护您的用户。通常情况下,这种共享是完全被禁止的,因此 CORS 是一种在浏览器的正常安全策略中戳破漏洞的方法。这些漏洞应该尽可能小,因此请务必根据某种内部列表检查 HTTP_ORIGIN。
这里存在一些危险,特别是如果 URL 提供的数据通常受到保护。您实际上是在允许源自其他服务器的浏览器内容读取(并可能操纵)您服务器上的数据。
如果您打算使用 CORS,请仔细阅读协议(它很小)并尝试了解您在做什么。代码示例中给出了用于此目的的参考 URL。
据观察,HTTP_ORIGIN 标头不安全,这是事实。事实上,所有 HTTP 标头对于该术语的不同含义都是不安全的。除非标头包含可验证的签名/hmac,或者整个对话通过 TLS 进行身份验证,否则标头只是“浏览器告诉我的内容”。
在这种情况下,浏览器会说“来自域 X 的对象想要从此 URL 获取响应。可以吗?” CORS 的重点是能够回答“是的,我会允许这样做”。
我遇到了同样的错误,并在后端脚本中使用以下 PHP 修复了它:
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET, POST');
header("Access-Control-Allow-Headers: X-Requested-With");
Access-Control-Allow-Headers
不允许 *
作为可接受的值,请参阅 Mozilla 文档此处。
您应该发送接受的标头(而不是星号)(首先是
X-Requested-With
,如错误所示)。
*
现已接受是Access-Control-Allow-Headers
。
根据 MDN Web 文档 2021:
值
仅算作没有凭据的请求(没有 HTTP cookie 或 HTTP 身份验证信息的请求)的特殊通配符值。在带有凭据的请求中,它被视为文字标头名称*
,没有特殊语义。请注意,授权标头不能使用通配符,并且始终需要显式列出。*
互联网上的许多描述都没有提到指定
Access-Control-Allow-Origin
是不够的。这是一个适合我的完整示例:
<?php
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: POST, GET, DELETE, PUT, PATCH, OPTIONS');
header('Access-Control-Allow-Headers: token, Content-Type');
header('Access-Control-Max-Age: 1728000');
header('Content-Length: 0');
header('Content-Type: text/plain');
die();
}
header('Access-Control-Allow-Origin: *');
header('Content-Type: application/json');
$ret = [
'result' => 'OK',
];
print json_encode($ret);
如果您想从 PHP 创建 CORS 服务,您可以使用此代码作为处理请求的文件中的第一步:
// Allow from any origin
if(isset($_SERVER["HTTP_ORIGIN"]))
{
// You can decide if the origin in $_SERVER['HTTP_ORIGIN'] is something you want to allow, or as we do here, just allow all
header("Access-Control-Allow-Origin: {$_SERVER['HTTP_ORIGIN']}");
}
else
{
//No HTTP_ORIGIN set, so we allow any. You can disallow if needed here
header("Access-Control-Allow-Origin: *");
}
header("Access-Control-Allow-Credentials: true");
header("Access-Control-Max-Age: 600"); // cache for 10 minutes
if($_SERVER["REQUEST_METHOD"] == "OPTIONS")
{
if (isset($_SERVER["HTTP_ACCESS_CONTROL_REQUEST_METHOD"]))
header("Access-Control-Allow-Methods: POST, GET, OPTIONS, DELETE, PUT"); //Make sure you remove those you do not want to support
if (isset($_SERVER["HTTP_ACCESS_CONTROL_REQUEST_HEADERS"]))
header("Access-Control-Allow-Headers: {$_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']}");
//Just exit with 200 OK with the above headers for OPTIONS method
exit(0);
}
//From here, handle the request as it is ok
我只是设法让 dropzone 和其他插件来处理此修复(angularjs + php 后端)
header('Access-Control-Allow-Origin: *');
header("Access-Control-Allow-Credentials: true");
header('Access-Control-Allow-Methods: GET, PUT, POST, DELETE, OPTIONS');
header('Access-Control-Max-Age: 1000');
header('Access-Control-Allow-Headers: Origin, Content-Type, X-Auth-Token , Authorization');
将其添加到您的 upload.php 或您要发送请求的位置(例如,如果您有 upload.html 并且您需要将文件附加到 upload.php,然后复制并粘贴这 4 行)。 另外,如果您在 chrome/mozilla 中使用 CORS 插件/附加组件,请务必多次切换它们,以便启用 CORS
当使用 Angular 4 作为客户端、PHP 作为服务器端时,这么多代码对我来说很有效。
header("Access-Control-Allow-Origin: *");
如果我们不能正确理解 CORS 的功能,它可能会让人头疼。我在 PHP 中使用它们并且它们工作没有问题。 参考这里
header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Credentials: true");
header("Access-Control-Max-Age: 1000");
header("Access-Control-Allow-Headers: X-Requested-With, Content-Type, Origin, Cache-Control, Pragma, Authorization, Accept, Accept-Encoding");
header("Access-Control-Allow-Methods: PUT, POST, GET, OPTIONS, DELETE");
这应该有效
header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Headers: X-Requested-With, Content-Type, Origin, Cache-Control, Pragma, Authorization, Accept, Accept-Encoding");
我使用了这5个标头,之后解决了cors错误(后端:PHP,前端:VUE JS)
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET, PUT, POST, DELETE, OPTIONS, post, get');
header('Access-Control-Max-Age: 3600');
header('Access-Control-Allow-Headers: Origin, Content-Type, X-Auth-Token');
header('Access-Control-Allow-Credentials: true');
将此代码添加到.htaccess
在标头中添加自定义身份验证密钥,如 app_key、auth_key ..etc
Header set Access-Control-Allow-Origin "*"
Header set Access-Control-Allow-Headers: "customKey1,customKey2, headers, Origin, X-Requested-With, Content-Type, Accept, Authorization"