了解 Access-Control-Allow-Origin 和缓存

Posted

技术标签:

【中文标题】了解 Access-Control-Allow-Origin 和缓存【英文标题】:Understanding Access-Control-Allow-Origin and caching 【发布时间】:2018-03-25 16:46:39 【问题描述】:

在查询 WordPress API 时,我认为原始标头的缓存存在问题。但是,我正在努力弄清楚到底发生了什么以及如何解决它。

首先 - 这是正在发生的事情:

我有一个 HubSpot 页面,该页面通过 ajax 查询 WordPress API,特别是 WP API 菜单插件添加的端点 - 然后我构建菜单,以便在客户端(或营销团队之一)在 WordPress 中更新时 - HubSpot 页面上的菜单也会更新。

HubSpot 页面位于 WordPress 站点的子域上,最初 WordPress 站点添加了标题 Access-Control-Allow-Origin 以及 只是 子域 URL明确设置。

如果我浏览到 HubSpot 中的编辑屏幕 - 主菜单不会加载,但第二次调用(针对不同的菜单)成功。主菜单报错如下:

“Access-Control-Allow-Origin”标头有一个值 'http://subdomain.example.com' 不等于提供的 起源。因此不允许使用原点“https://preview.hs-sites.com” 访问。

http://subdomain.example.com 是活动页面的 URL。奇怪的是,预览页面的实际 URL 不是 https://preview.hs-sites.com - 但我认为这可能是因为预览加载在 iframe 中。

现在,当我转到实时 URL 时,会发生同样的事情 - 第一次调用出错,但第二次成功。这次报错如下:

“Access-Control-Allow-Origin”标头有一个值 'https://preview.hs-sites.com' 不等于提供的 起源。因此不允许使用原点“http://subdomain.example.com” 访问。


问题 1 - 这是因为源已被 WordPress 网站?

我现在已将 http://subdomain.example.com 和 https://preview.hs-sites.com 添加到 WordPress 中的 allowed_http_origins 过滤器 - 如下:

add_filter( 'allowed_http_origins', 'my_add_origins' );
function my_add_origins($origins) 
    $origins[] = 'https://preview.hs-sites.com';
    $origins[] = 'http://subdomain.example.com';
    return $origins;

问题 2:不管假定的缓存是什么 - 为什么是 https://preview.hs-sites.com 如果已添加,则不可接受 允许的来源?

我不确定如何测试上述功能 - 所以我也尝试了以下方法:

add_action( 'rest_api_init', function() 
    remove_filter('rest_pre_serve_request', 'rest_send_cors_headers');
    add_filter('rest_pre_serve_request', function($value) 
        $domains = [
            'https://preview.hs-sites.com',
            'http://subdomain.example.com'
        ];
        $allowed = get_http_origin();
        if ($allowed && (in_array($allowed, $domains))) 
            header("Access-Control-Allow-Origin:" . esc_url_raw($allowed));
         elseif (!$allowed) 
            header("Access-Control-Allow-Origin: http://subdomain.example.com");
        
        header('Access-Control-Allow-Methods: GET');

        return $value;
    );
);

但是会发生完全相同的错误。

问题 3:有人能解释一下发生的过程吗 在这种情况下以及错误在说什么 - 特别是在哪里 他们从中获取价值 - 原点是当前页面吗?和 'Access-Control-Allow-Origin' 标头有一个值' ... - 这个 值是由任何已设置为 WordPress 中的 Access-Control-Allow-Origin 标头 - 正确吗?

注意我也尝试在 ajax 请求中设置 no-cache 标头,但由于预检请求而出现此错误。我还在请求中添加了一个随机查询字符串,但没有任何效果。

出于安全原因,我想避免将通配符值添加为 Access-Control-Allow-Origin 标头。我真的很想了解发生了什么!

【问题讨论】:

【参考方案1】:

尝试将值为OriginVary 响应标头添加到服务器响应中。

Origin 请求标头的值与其缓存的请求的Origin 值不同时,这应该会导致任何浏览器跳过其缓存并发出新的网络请求。

有关更多信息,请参阅the MDN article on the Vary response header。

Vary HTTP 响应头决定了如何匹配未来的请求 标头来决定是否可以使用缓存的响应而不是 从源服务器请求一个新的。它被使用 服务器指示它在选择一个 内容协商算法中资源的表示。

【讨论】:

以上是关于了解 Access-Control-Allow-Origin 和缓存的主要内容,如果未能解决你的问题,请参考以下文章

SpringBoot跨域

SpringBoot跨域

SpringBoot跨域

如何通过CORS传递cookie?

node.js创建简单服务测试请求数据

利用Filter解决跨域请求的问题