本文介绍了浏览器中的CORS标头已更改,导致内容被阻止的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

更新2(完整的日志集)

响应标头:

控制台错误:

控制台警告:

从服务器的角度来看

这是服务器说已接收和发送的内容(请检查执行更新1记录的代码):

From Server's Perspective

This is what the server says it has received and sent (check the code that does the logging in update 1):

Array
(
    [req] => Array
        (
            ...
            [HTTP_ORIGIN] => https://debug.dev
            ...
        )

    [rsp] => Array
        (
            [0] => X-Powered-By: PHP/5.5.9-1ubuntu4.17
            [1] => Access-Control-Allow-Origin: https://debug.dev
            [2] => Access-Control-Allow-Methods: GET, POST, OPTIONS
            [3] => Access-Control-Allow-Credentials: true
        )

)


更新

我已经在服务器上添加了一些日志,脚本现在从以下几行开始:

I have added some logging on the server and the script now begins with these lines:

# allow access from other domains
    header("Access-Control-Allow-Origin: " . $_SERVER['HTTP_ORIGIN']);
    header("Access-Control-Allow-Methods: GET, POST, OPTIONS");
    header("Access-Control-Allow-Credentials: true");

$all = [
    'req' => $_SERVER,
    'rsp' => headers_list()
];

$s = print_r($all, true);
$p = '/var/www/path/to/file_' . uniqid() . '.txt';
file_put_contents($p, $s);

这样,我可以确认请求以正确的Origin到达服务器,并且服务器发送回正确的CORS标头.但是,开发者控制台中的Access-Control-Allow-Origin是错误的,请求已被阻止.

With this I can confirm that the request arrives on the server with the correct Origin, AND the server sends back the correct CORS headers. Yet, the Access-Control-Allow-Origin in the developer console is wrong and the request is blocked.

以下是通过上面的代码获得的精简日志:

Here is a stripped down log obtained with the code above:

Array
(
    [req] => Array
        (
            ...
            [HTTP_ORIGIN] => https://debug.dev
            ...
        )

    [rsp] => Array
        (
            [0] => X-Powered-By: PHP/5.5.9-1ubuntu4.17
            [1] => Access-Control-Allow-Origin: https://debug.dev
            [2] => Access-Control-Allow-Methods: GET, POST, OPTIONS
            [3] => Access-Control-Allow-Credentials: true
        )

)

问题

当收到的实际标头为Access-Control-Allow-Origin: https://debug.dev时,如何以及为何将Access-Control-Allow-Origin更改为https://production.com?

How and why does the Access-Control-Allow-Origin is changed to https://production.com when the actual header received is Access-Control-Allow-Origin: https://debug.dev?

(原始帖子)

背景

我有一个基于Web的调试工具,已将其安装在本地开发计算机上.在/etc/hosts中的一个条目中,我已将其分配给域debug.dev.我还添加了本地CA权限,并已成功为域名创建了SSL证书,因此现在我可以在浏览器中打开https://debug.dev/,调试工具将正常打开.

I have a web-based debug tool that I have installed on my local development machine. With an entry in my /etc/hosts I have assigned to it the domain debug.dev. I have also added a local CA authority and have successfully created a SSL certificate for the domain name so now I can open https://debug.dev/ in my browser and the debug tool opens normally.

该工具应该与登台服务器和生产服务器一起使用.因此,它需要将AJAX请求发送到其他域.我对这些服务器拥有完全控制权,并且正在从这些服务器发送回CORS标头,如下所示:

This tool is supposed to work with staging and production servers. So it needs to send AJAX requests to other domains. I have full control over those servers and I am sending back CORS headers from those servers like so:

header("Access-Control-Allow-Origin: " . $_SERVER['HTTP_ORIGIN']);
header("Access-Control-Allow-Credentials: true");

问题

现在,我面临着莫名其妙的局面,当我向生产服务器发送AJAX请求时,我得到了服务器域的错误 CORS标头:

Now I am facing a baffling situation in which when I send an AJAX request to the production server I get back Wrong CORS headers with the SERVER's domain like this:

但是,如果我右键单击并使用在新标签页中打开,则CORS标头应为原标题;即

But if I right click and use Open in new tab the CORS headers are what they ought to be; i.e.

据我所知,请求之间的唯一区别是,第一个请求是作为AJAX POST请求发送的,因此发送的是HTTP_X_REQUESTED_WITH标头,而第二个请求是作为普通的GET请求发送的.服务器如何返回不同的CORS标头?

The only differences between the requests as far as I can see is that the first one is sent as an AJAX POST request and thus sends a HTTP_X_REQUESTED_WITH header whereas the second request is sent as an ordinary GET request. How could this result in a different CORS header be returned by the server?

推荐答案

问题可能与:

在新标签页中打开网址是一个 GET 请求,并且正在运行,因为它满足要求时未发出预检请求成为简单请求的标准, CORS文档

Opening the url in a new Tab is a GET request and is working because it is not making a preflight request, as it meets the criteria to be a simple request as defined by the CORS documentation

另一方面, ajax请求是一个 POST 请求,并且满足成为已取消请求,这意味着应首先发出预检选项请求.

On the other hand, the ajax request is a POST request and meets the criteria to be a Preflighted request, meaning a preflight OPTIONS request should be made first.

简而言之,您已经正确设置了CORS响应标头,但是未将服务器配置为添加这些标头用于OPTIONS方法请求.

In short, you have correctly setup the CORS response headers, but the server is not configured to add these headers for OPTIONS method requests.

解决方案是使用 2xx响应处理服务器代码上的选项请求,并添加** Access-Control-Allow-就像您处理GET和POST请求一样.请记住,OPTIONS请求不包含任何参数,因此应在进行任何验证或请求解析之前完成.

The solution is to handle OPTIONS requests on the server code with a 2xx response and add the **Access-Control-Allow- as you do for GET and POST requests. Keep in mind that OPTIONS requests do not include any parameters, so this should be done before any validation or request parsing.

此外,根据访问权限-Control-Allow-Origin文档:

因此,还要设置 Var 响应标头:

So set the Vary response header also:

例如在您脚本的顶部尝试:

eg at the top of you script try:

if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
    header("Access-Control-Allow-Origin: " . $_SERVER['HTTP_ORIGIN']);
    header("Access-Control-Allow-Methods: GET, POST, OPTIONS");
    header("Access-Control-Allow-Credentials: true");
    header("Vary: Origin");
    exit;
}

参考文献

优先请求

禁止对飞行前403的响应

这篇关于浏览器中的CORS标头已更改,导致内容被阻止的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

06-27 04:48
查看更多