【问题标题】:Why does No 'Access-Control-Allow-Origin' is not enforced when I call third party services, but it is when I call my own server?为什么当我调用第三方服务时没有强制执行“访问控制允许来源”,但是当我调用自己的服务器时?
【发布时间】:2015-09-25 18:25:54
【问题描述】:

我正在JAX-RS 服务器上构建一个RESTful 服务和一些将附加到它的客户端。

开始测试客户端端点的时间到了,我首先在JavaScript 上进行了尝试,因为到目前为止,我很容易使用此代码向第三方资源发出请求:

function httpGet(theUrl){
            var xmlHttp = new XMLHttpRequest();
            xmlHttp.open( "GET", theUrl, false );
            xmlHttp.send( null );
            return xmlHttp.responseText;
}

我知道我不应该执行同步请求,但那不是主题。

在 Firefox 上,我得到的错误是:

Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://someurl.com/someresource/. (Reason: CORS header 'Access-Control-Allow-Origin' missing).

这些请求在我的本地服务器和部署服务器上都不起作用。

我发现这个问题的大多数解决方案都必须通过设置标题Access-Control-Allow-Origin: * 来做一些事情。我已经尝试过了,但它对我没有用。

起初我以为是我的服务器配置有问题,但现在我认为是浏览器因为同源策略而不允许我执行请求。这个对吗?如果正确,为什么与上面完全相同的代码(没有Access-Control-Allow-Headers: *)适用于第三方服务(Google、Facebook 等)?

是否存在始终允许违反同源政策的网站白名单?

如果最后一个问题的答案是否定的,那么他们必须在其服务器端代码上进行一些特定的配置,以允许跨域通信发生。这个配置可能是什么?

【问题讨论】:

  • 试试 Access-Control-Allow-Origin 不是 Access-Control-Allow-Headers
  • 我认为这取决于服务器配置。 IE。在 php 中,您应该将标头设置为 'header("Access-Control-Allow-Origin: *");'允许 cors 请求。
  • 谢谢@DavePile 这是一个错字,我试过 Access-Control-Allow-Origin 没有运气...
  • 我确信那些第三方服务在后端支持 CORS。
  • See

标签: javascript rest jax-rs


【解决方案1】:

一开始我以为是我的服务器配置有问题

是的。

但现在我认为是浏览器不允许我执行请求,因为同源策略。

确实如此。浏览器不允许根据 SOP 的请求因为您的服务器未配置为允许跨域请求。

这不仅仅是传回一个标头。 Full details in the spec,但基本上归结为:

  1. 响应OPTIONS请求,而不仅仅是GETPOST等。

  2. 使用所有必要的标题进行响应。

  3. 以正确的值响应这些标头。

您必须发回的标头至少是:

  • Access-Control-Allow-Origin
  • Access-Control-Allow-Methods
  • Access-Control-Allow-Headers

您可能还需要Access-Control-Allow-Credentials。您需要为这些提供的值通常来自请求附带的具有相似(但略有不同)名称的标头。

您必须同时提供标头以响应 OPTIONS 调用(如果有)以及随后的 GETPOST 等调用。

如果正确,为什么与上面完全相同的代码(没有 Access-Control-Allow-Headers: *)适用于第三方服务(Google、Facebook 等)?

浏览器自动填写请求头;不同的是服务器响应请求。

是否存在始终允许违反同源政策的网站白名单?

不,当然不是。

如果最后一个问题的答案是否定的,那么他们必须在其服务器端代码上进行一些特定的配置,以允许跨域通信发生。这个配置可能是什么?

以上。

以下是 服务器 端通过 CORS 授予访问权限的一些伪代码(它是用 JavaScript 编写的,因为我知道您熟悉 JavaScript,但它伪代码,并且您需要在您的服务器上执行此操作):

var origin, method, headers;
origin = getRequestHeader("Origin");
if (origin /* and you want to grant access to it */) {
    addResponseHeader("Access-Control-Allow-Origin", origin);
    method = getRequestHeader("Access-Control-Request-Method");
    if (method) {
        // Note the request header is singular, but the response header is plural
        addResponseHeader("Access-Control-Allow-Methods", method);
    }
    headers = getRequestHeader("Access-Control-Request-Headers");
    if (headers) {
        addResponseHeader("Access-Control-Allow-Headers", headers);
    }
    if (/* You want to allow the origin to provide credentials and cookies*/) {
        addResponseHeader("Access-Control-Allow-Credentials", "true");
    }
}

【讨论】:

  • 谢谢!我仍然需要实现伪代码,但您的回答消除了我的许多顾虑。
【解决方案2】:

起初我以为是我的服务器配置有问题,但现在我认为是浏览器因为同源策略而不允许我执行请求。这个对吗?

默认,浏览器将执行同源策略并阻止您的 JavaScript 访问数据。

您发出请求的服务器的配置可以设置 CORS 标头(包括 Access-Control-Allow-OriginAccess-Control-Allow-Headers)以告诉浏览器对该请求执行同源策略。

是否存在始终允许违反同源政策的网站白名单?

没有

如果最后一个问题的答案是否定的,那么他们必须在其服务器端代码上进行一些特定的配置,以允许跨域通信发生。这个配置可能是什么?

配置设置您引用的错误消息中描述的响应标头。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-11-14
    • 1970-01-01
    • 2017-11-03
    • 1970-01-01
    • 2020-03-10
    • 2017-06-12
    • 2021-10-08
    • 2017-06-19
    相关资源
    最近更新 更多