dozug64282 2017-10-13 14:05
浏览 55
已采纳

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

I have an issue with what I believe to be caching of the origin header when querying the WordPress API. However, I am struggling to work out exactly what is happening and how I can fix it.

First - here's what's happening:

I have a HubSpot page that queries via ajax the WordPress API and specifically the endpoints added by the WP API Menus plugin - I then build the menu so that when updated in WordPress by the client (or one of the marketing team) - the menu is updated on the HubSpot pages too.

The HubSpot page is on a subdomain of the WordPress site, and initially the WordPress site had the header Access-Control-Allow-Origin added with just the subdomain URL explicitly set.

If I browse to the edit screen within HubSpot - the main menu doesn't load, but the second call (for a different menu) succeeds. The error for the main menu is as follows:

The 'Access-Control-Allow-Origin' header has a value 'http://subdomain.example.com' that is not equal to the supplied origin. Origin 'https://preview.hs-sites.com' is therefore not allowed access.

The http://subdomain.example.com being the URL of the live page. Strangely the actual URL of the preview page is not https://preview.hs-sites.com - but I assume this may be because perhaps preview loads in an iframe.

Now, when I then go to the live URL, the same thing happens - the first call errors, but the second succeeds. This time the error is as follows:

The 'Access-Control-Allow-Origin' header has a value 'https://preview.hs-sites.com' that is not equal to the supplied origin. Origin 'http://subdomain.example.com' is therefore not allowed access.


Question 1 - is this because the origin has been cached by the WordPress site?

I have now added both http://subdomain.example.com and https://preview.hs-sites.com to the allowed_http_origins filter within WordPress - as follows:

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;
}

Question 2: Regardless of the presumed caching - why is https://preview.hs-sites.com not acceptable if it has been added to the allowed origins?

I was unsure how to test the above function - so I also tried the following:

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;
    });
});

But the exact same errors occur.

Question 3: Could somebody please explain the process that takes place in this situation and what the errors are saying - specifically where they are getting their values from - is origin the current page? And the 'The 'Access-Control-Allow-Origin' header has a value' ... - this value is being set by whatever has been set as the Access-Control-Allow-Origin header in WordPress - correct?

Note I have also tried setting no-cache header in the ajax request, but this errors because of the preflight request. I've also added a random querystring to the request, which has no effect.

I'd like to avoid adding a wildcard value as the Access-Control-Allow-Origin header for security reasons. And I'd really like to understand what's going on!

  • 写回答

1条回答 默认 最新

  • dtevhgk028372 2017-10-13 17:18
    关注

    Try adding a Vary response header with the value Origin to the server response.

    That should have the effect of causing any browser to skip its cache and make a new network request when the value of the Origin request header is different from the Origin value of the request it cached from.

    For a bit more info, see the MDN article on the Vary response header.

    The Vary HTTP response header determines how to match future request headers to decide whether a cached response can be used rather than requesting a fresh one from the origin server. It is used by the server to indicate which headers it used when selecting a representation of a resource in a content negotiation algorithm.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 opencv 无法读取视频
  • ¥15 用matlab 实现通信仿真
  • ¥15 按键修改电子时钟,C51单片机
  • ¥60 Java中实现如何实现张量类,并用于图像处理(不运用其他科学计算库和图像处理库))
  • ¥20 5037端口被adb自己占了
  • ¥15 python:excel数据写入多个对应word文档
  • ¥60 全一数分解素因子和素数循环节位数
  • ¥15 ffmpeg如何安装到虚拟环境
  • ¥188 寻找能做王者评分提取的
  • ¥15 matlab用simulink求解一个二阶微分方程,要求截图