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

时间:2017-10-13 14:05:13

标签: php wordpress caching http-headers cors

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

首先 - 这里发生了什么:

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

HubSpot页面位于WordPress站点的子域中,最初WordPress站点的标题为Access-Control-Allow-Origin,其中包含 子域URL明确设定。

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

  

' Access-Control-Allow-Origin' header有一个值   ' http://subdomain.example.com'这不等于提供的   起源。起源' https://preview.hs-sites.com'因此是不允许的   访问。

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

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

  

' Access-Control-Allow-Origin' header有一个值   ' https://preview.hs-sites.com'这不等于提供的   起源。起源' http://subdomain.example.com'因此是不允许的   访问。

  

问题1 - 这是因为原点已被缓存了   WordPress网站?

我现在已将http://subdomain.example.comhttps://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:有人可以解释发生的过程   在这种情况下,错误是什么 - 特别是在哪里   他们从中获取价值 - 来自当前页面?和   '访问控制 - 允许 - 来源'标头有一个值' ... - 这个   值被设置为的任何值设置   WordPress中的Access-Control-Allow-Origin标头 - 正确吗?

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

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

1 个答案:

答案 0 :(得分:1)

尝试将值Vary的{​​{1}}响应标头添加到服务器响应中。

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

有关详情,请参阅the MDN article on the Vary response header

  

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