Javascript 规避同源策略的方法
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3076414/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Ways to circumvent the same-origin policy
提问by David Titarenco
The same origin policy
同源政策
I wanted to make a community wiki regarding HTML/JS same-origin policiesto hopefully help anyone searching for this topic. This is one of the most searched-for topics on SO and there is no consolidated wiki for it so here I go :)
我想制作一个关于 HTML/JS同源策略的社区 wiki ,希望能帮助任何搜索此主题的人。这是 SO 上搜索次数最多的主题之一,并且没有统一的 wiki,所以我在这里:)
The same origin policy prevents a document or script loaded from one origin from getting or setting properties of a document from another origin. This policy dates all the way back to Netscape Navigator 2.0.
同源策略可防止从一个源加载的文档或脚本从另一个源获取或设置文档的属性。该政策可追溯到 Netscape Navigator 2.0。
What are some of your favorite ways to go around same-origin policies?
您最喜欢的绕过同源策略的一些方法是什么?
Please keep examples verbose and preferably also link your sources.
请保持示例详细,最好还链接您的来源。
采纳答案by David Titarenco
The document.domainmethod
该document.domain方法
- Method type: iframe.
- 方法类型:iframe。
Note that this is an iframe method that sets the value of document.domain to a suffix of the current domain. If it does so, the shorter domain is used for subsequent origin checks. For example, assume a script in the document at http://store.company.com/dir/other.htmlexecutes the following statement:
请注意,这是一个 iframe 方法,它将 document.domain 的值设置为当前域的后缀。如果是这样,较短的域将用于后续的源检查。例如,假设文档中的脚本http://store.company.com/dir/other.html执行以下语句:
document.domain = "company.com";
After that statement executes, the page would pass the origin check with http://company.com/dir/page.html. However, by the same reasoning, company.com could not set document.domainto othercompany.com.
该语句执行后,页面将通过原始检查http://company.com/dir/page.html。但是,出于同样的原因,company.com 无法设置document.domain为othercompany.com.
With this method, you would be allowed to exectue javascript from an iframe sourced on a subdomain on a page sourced on the main domain. This method is not suited for cross-domain resources as browsers like Firefox will not allow you to change the document.domainto a completely alien domain.
使用此方法,您将被允许从源自主域的页面上的子域上的 iframe 执行 javascript。这种方法不适合跨域资源,因为像 Firefox 这样的浏览器不允许您将其更改document.domain为完全陌生的域。
Source: https://developer.mozilla.org/en/Same_origin_policy_for_JavaScript
来源:https: //developer.mozilla.org/en/Same_origin_policy_for_JavaScript
The Cross-Origin Resource Sharing method
跨域资源共享方式
- Method type: AJAX.
- 方法类型:AJAX。
Cross-Origin Resource Sharing(CORS) is a W3C Working Draft that defines how the browser and server must communicate when accessing sources across origins. The basic idea behind CORS is to use custom HTTP headers to allow both the browser and the server to know enough about each other to determine if the request or response should succeed or fail.
跨域资源共享(CORS) 是 W3C 工作草案,它定义了浏览器和服务器在跨域访问源时必须如何通信。CORS 背后的基本思想是使用自定义 HTTP 标头来允许浏览器和服务器充分了解彼此,以确定请求或响应是成功还是失败。
For a simple request, one that uses either GETor POSTwith no custom headers and whose body is text/plain, the request is sent with an extra header called Origin. The Origin header contains the origin (protocol, domain name, and port) of the requesting page so that the server can easily determine whether or not it should serve a response. An example Originheader might look like this:
对于一个简单的请求,即使用GET或POST不使用自定义标头且主体为 的简单请求,将使用text/plain名为 的额外标头发送请求Origin。Origin 标头包含请求页面的来源(协议、域名和端口),以便服务器可以轻松确定它是否应该提供响应。示例Origin标题可能如下所示:
Origin: http://www.stackoverflow.com
If the server decides that the request should be allowed, it sends a Access-Control-Allow-Originheader echoing back the same origin that was sent or *if it's a public resource. For example:
如果服务器决定应该允许该请求,它会发送一个Access-Control-Allow-Origin标头,回显发送的同一来源或者*它是否是公共资源。例如:
Access-Control-Allow-Origin: http://www.stackoverflow.com
If this header is missing, or the origins don't match, then the browser disallows the request. If all is well, then the browser processes the request. Note that neither the requests nor responses include cookie information.
如果缺少此标头,或来源不匹配,则浏览器将禁止该请求。如果一切顺利,浏览器就会处理请求。请注意,请求和响应都不包含 cookie 信息。
The Mozilla team suggests in their post about CORSthat you should check for the existence of the withCredentialsproperty to determine if the browser supports CORS via XHR. You can then couple with the existence of the XDomainRequestobject to cover all browsers:
Mozilla 团队在他们关于 CORS 的帖子中建议您应该检查该withCredentials属性是否存在,以确定浏览器是否通过 XHR 支持 CORS。然后你可以结合XDomainRequest对象的存在来覆盖所有浏览器:
function createCORSRequest(method, url){
var xhr = new XMLHttpRequest();
if ("withCredentials" in xhr){
xhr.open(method, url, true);
} else if (typeof XDomainRequest != "undefined"){
xhr = new XDomainRequest();
xhr.open(method, url);
} else {
xhr = null;
}
return xhr;
}
var request = createCORSRequest("get", "http://www.stackoverflow.com/");
if (request){
request.onload = function() {
// ...
};
request.onreadystatechange = handler;
request.send();
}
Note that for the CORS method to work, you need to have access to any type of server header mechanic and can't simply access any third-party resource.
请注意,要使 CORS 方法起作用,您需要有权访问任何类型的服务器标头机制,而不能简单地访问任何第三方资源。
Source: http://www.nczonline.net/blog/2010/05/25/cross-domain-ajax-with-cross-origin-resource-sharing/
来源:http: //www.nczonline.net/blog/2010/05/25/cross-domain-ajax-with-cross-origin-resource-sharing/
The window.postMessagemethod
该window.postMessage方法
- Method type: iframe.
- 方法类型:iframe。
window.postMessage, when called, causes a MessageEventto be dispatched at the target window when any pending script that must be executed completes (e.g. remaining event handlers if window.postMessageis called from an event handler, previously-set pending timeouts, etc.). The MessageEventhas the type message, a dataproperty which is set to the string value of the first argument provided to window.postMessage, an originproperty corresponding to the origin of the main document in the window calling window.postMessageat the time window.postMessagewas called, and a sourceproperty which is the window from which window.postMessageis called.
window.postMessage,当被调用时,导致MessageEvent在任何必须执行的挂起脚本完成时在目标窗口分派a (例如,如果window.postMessage从事件处理程序中调用剩余的事件处理程序,先前设置的挂起超时等)。的MessageEvent具有类型消息,data其被设置为提供到所述第一参数的字符串值属性window.postMessage,一个origin对应于窗口调用主文档的原点属性window.postMessage在时间window.postMessage被调用,并且一个source属性,该属性是窗口从这window.postMessage被称为。
To use window.postMessage, an event listener must be attached:
要使用window.postMessage,必须附加事件侦听器:
// Internet Explorer
window.attachEvent('onmessage',receiveMessage);
// Opera/Mozilla/Webkit
window.addEventListener("message", receiveMessage, false);
And a receiveMessagefunction must be declared:
并且receiveMessage必须声明一个函数:
function receiveMessage(event)
{
// do something with event.data;
}
The off-site iframe must also send events properly via postMessage:
场外 iframe 还必须通过postMessage以下方式正确发送事件:
<script>window.parent.postMessage('foo','*')</script>
Any window may access this method on any other window, at any time, regardless of the location of the document in the window, to send it a message. Consequently, any event listener used to receive messages must first check the identity of the sender of the message, using the origin and possibly source properties. This cannot be understated: Failure to check the originand possibly sourceproperties enables cross-site scripting attacks.
任何窗口都可以在任何其他窗口上访问此方法,无论文档在窗口中的位置如何,都可以随时向其发送消息。因此,任何用于接收消息的事件侦听器都必须首先使用源和可能的源属性检查消息发送者的身份。不能低估这一点:未能检查origin和可能的source属性会导致跨站点脚本攻击。
Source: https://developer.mozilla.org/en/DOM/window.postMessage
回答by Daniel Vassallo
The Reverse Proxy method
反向代理方法
- Method type: Ajax
- 方法类型:Ajax
Setting up a simple reverse proxyon the server, will allow the browser to use relative paths for the Ajax requests, while the server would be acting as a proxy to any remote location.
在服务器上设置一个简单的反向代理,将允许浏览器使用 Ajax 请求的相对路径,而服务器将充当任何远程位置的代理。
If using mod_proxyin Apache, the fundamental configuration directive to set up a reverse proxy is the ProxyPass. It is typically used as follows:
如果在 Apache 中使用mod_proxy,则设置反向代理的基本配置指令是ProxyPass. 它通常如下使用:
ProxyPass /ajax/ http://other-domain.com/ajax/
In this case, the browser would be able to request /ajax/web_service.xmlas a relative URL, but the server would serve this by acting as a proxy to http://other-domain.com/ajax/web_service.xml.
在这种情况下,浏览器将能够以/ajax/web_service.xml相对 URL 的形式请求,但服务器将通过充当 的代理来提供服务http://other-domain.com/ajax/web_service.xml。
One interesting feature of the this method is that the reverse proxy can easily distribute requests towards multiple back-ends, thus acting as a load balancer.
此方法的一个有趣特性是反向代理可以轻松地将请求分发到多个后端,从而充当负载均衡器。
回答by Nicolas Viennot
I use JSONP.
我使用 JSONP。
Basically, you add
基本上,你添加
<script src="http://..../someData.js?callback=some_func"/>
on your page.
在您的页面上。
some_func() should get called so that you are notified that the data is in.
some_func() 应该被调用,以便通知您数据在。
回答by ripper234
AnyOrigin didn't function well with some https sites, so I just wrote an open source alternative called whateverorigin.orgthat seems to work well with https.
AnyOrigin没有一些https网站运行良好,所以我只是写一个开源替代whateverorigin.org,似乎以https很好地工作。
回答by Mat Schaffer
I can't claim credit for this image, but it matches everything I know on this subject and offers a bit of humor at the same time.
我不能为这张图片声明功劳,但它符合我在这个主题上所知道的一切,同时提供了一点幽默。
回答by rk1s
The most recent way of overcoming the same-origin policy that I've found is http://anyorigin.com/
克服我发现的同源策略的最新方法是http://anyorigin.com/
The site's made so that you just give it any url and it generates javascript/jquery code for you that lets you get the html/data, regardless of it's origin. In other words, it makes any url or webpage a JSONP request.
该网站的制作使您只需给它任何网址,它就会为您生成 javascript/jquery 代码,让您可以获取 html/data,无论其来源如何。换句话说,它使任何 url 或网页成为 JSONP 请求。
I've found it pretty useful :)
我发现它非常有用:)
Here's some example javascript code from anyorigin:
下面是来自 anyorigin 的一些示例 javascript 代码:
$.getJSON('http://anyorigin.com/get?url=google.com&callback=?', function(data){
$('#output').html(data.contents);
});
回答by Sarfraz
The JSONPcomes to mind:
该JSONP想到:
JSONP or "JSON with padding" is a complement to the base JSON data format, a usage pattern that allows a page to request and more meaningfully use JSON from a server other than the primary server. JSONP is an alternative to a more recent method called Cross-Origin Resource Sharing.
JSONP 或“带填充的 JSON”是对基本 JSON 数据格式的补充,这是一种使用模式,允许页面从主服务器以外的服务器请求并更有意义地使用 JSON。JSONP 是一种称为跨源资源共享的最新方法的替代方法。
回答by harihb
Well, I used curl in PHP to circumvent this. I have a webservice running in port 82.
好吧,我在 PHP 中使用 curl 来规避这一点。我有一个运行在 82 端口的网络服务。
<?php
$curl = curl_init();
$timeout = 30;
$ret = "";
$url="http://localhost:82/put_val?val=".$_GET["val"];
curl_setopt ($curl, CURLOPT_URL, $url);
curl_setopt ($curl, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt ($curl, CURLOPT_MAXREDIRS, 20);
curl_setopt ($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt ($curl, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.9.0.5) Gecko/2008120122 Firefox/3.0.5");
curl_setopt ($curl, CURLOPT_CONNECTTIMEOUT, $timeout);
$text = curl_exec($curl);
echo $text;
?>
Here is the javascript that makes the call to the PHP file
这是调用 PHP 文件的 javascript
function getdata(obj1, obj2) {
var xmlhttp;
if (window.XMLHttpRequest)
xmlhttp=new XMLHttpRequest();
else
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
xmlhttp.onreadystatechange=function()
{
if (xmlhttp.readyState==4 && xmlhttp.status==200)
{
document.getElementById("txtHint").innerHTML=xmlhttp.responseText;
}
}
xmlhttp.open("GET","phpURLFile.php?eqp="+obj1+"&val="+obj2,true);
xmlhttp.send();
}
My HTML runs on WAMP in port 80. So there we go, same origin policy has been circumvented :-)
我的 HTML 在端口 80 的 WAMP 上运行。所以我们走了,同源策略已被规避:-)
回答by Thiru
Here are some workarounds and explanation of same-origin-policy:
Thiru's Blog - Browser same origin policy workaround
以下是同源策略的一些解决方法和解释:
Thiru 的博客 - 浏览器同源策略解决方法
回答by Chris Cinelli
This analyze pretty much what is available out there: http://www.slideshare.net/SlexAxton/breaking-the-cross-domain-barrier
这几乎分析了那里可用的内容:http: //www.slideshare.net/SlexAxton/break-the-cross-domain-barrier
For postMessage solution take a look to:
对于 postMessage 解决方案,请查看:
https://github.com/chrissrogers/jquery-postmessage/blob/master/jquery.ba-postmessage.js
https://github.com/chrissrogers/jquery-postmessage/blob/master/jquery.ba-postmessage.js
and a slightly different version:
和一个略有不同的版本:
https://github.com/thomassturm/ender-postmessage/blob/master/ender-postmessage.js
https://github.com/thomassturm/ender-postmessage/blob/master/ender-postmessage.js

