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 关于#matlab#的问题:期望的系统闭环传递函数为G(s)=wn^2/s^2+2¢wn+wn^2阻尼系数¢=0.707,使系统具有较小的超调量
  • ¥15 FLUENT如何实现在堆积颗粒的上表面加载高斯热源
  • ¥30 截图中的mathematics程序转换成matlab
  • ¥15 动力学代码报错,维度不匹配
  • ¥15 Power query添加列问题
  • ¥50 Kubernetes&Fission&Eleasticsearch
  • ¥15 報錯:Person is not mapped,如何解決?
  • ¥15 c++头文件不能识别CDialog
  • ¥15 Excel发现不可读取的内容
  • ¥15 关于#stm32#的问题:CANOpen的PDO同步传输问题