我正在 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 等)?
是否存在始终允许违反同源策略的网站的白名单?
如果最后一个问题的答案是否定的,那么他们必须在他们的服务器端代码上进行一些特定的配置以允许跨源通信发生。这个配置可能是什么?
最佳答案
At first I thought it was a problem with my server configuration
是的。
but now I think it's the browser that is not letting me execute the request because of the Same Origin Policy.
没错。浏览器根据 SOP 拒绝请求,因为您的服务器未配置为允许跨源请求。
它不仅仅是传回一个 header 。 Full details in the spec , 但基本上可以归结为:
响应
OPTIONS
请求,而不仅仅是GET
、POST
等。使用所有必要的 header 进行响应。
使用这些 header 的正确值进行响应。
您必须发回的 header 至少是:
Access-Control-Allow-Origin
访问控制允许方法
Access-Control-Allow-Headers
您可能还需要 Access-Control-Allow-Credentials
。您需要为这些提供的值通常来自请求随附的名称相似(但略有不同)的 header 。
您必须提供 header 以响应 OPTIONS
调用(如果有的话),以及随后的 GET
或 POST
等调用。
If it's correct, why does the exact same code as above, with no Access-Control-Allow-Headers: *, works for third party services (Google, Facebook, etc.)?
浏览器自动填写请求头;不同之处在于服务器响应请求。
Is there a whitelist of sites that are always allowed to break the Same Origin Policy?
不,当然不是。
If the answer to the last question is no, then they must have some specific configutation on their server side code to allow Cross Origin communications to happen. What could this configuration be?
以上。
这是服务器通过 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");
}
}
关于javascript - 为什么我调用第三方服务时不强制执行No 'Access-Control-Allow-Origin',而调用我自己的服务器时却强制执行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32779848/