如何规避同源政策

Dav*_*nco 150 javascript ajax same-origin-policy

同样的原产地政策

我想制作一个关于HTML/JS 同源政策的社区维基,希望能帮助任何人搜索这个主题.这是SO上搜索次数最多的主题之一,没有统一的wiki,所以我去:)

相同的源策略可防止从一个源加载的文档或脚本从另一个源获取或设置文档的属性.此政策可以追溯到Netscape Navigator 2.0.

您最喜欢采用同源政策的方式有哪些?

请保持示例详细,最好还链接您的来源.

Dav*_*nco 84

document.domain方法

  • 方法类型:iframe.

请注意,这是一个iframe方法,它将document.domain的值设置为当前域的后缀.如果它这样做,则较短的域用于后续的原始检查.例如,假设文档中的脚本http://store.company.com/dir/other.html执行以下语句:

document.domain = "company.com";
Run Code Online (Sandbox Code Playgroud)

执行该语句后,页面将通过原始检查http://company.com/dir/page.html.然而,同样的道理,company.com不能设置document.domainothercompany.com.

使用此方法,您将被允许从源自主域上的页面上的子域的iframe中提取javascript.此方法不适用于跨域资源,因为Firefox等浏览器不允许您将其更改document.domain为完全异域.

资料来源:https://developer.mozilla.org/en/Same_origin_policy_for_JavaScript

跨源资源共享方法

  • 方法类型:AJAX.

跨源资源共享(CORS)是W3C工作草案,它定义了在访问源的源时浏览器和服务器必须如何通信.CORS背后的基本思想是使用自定义HTTP标头,允许浏览器和服务器相互了解,以确定请求或响应是成功还是失败.

对于一个简单的请求,一个使用任一GETPOST没有自定义首部,并且其体是text/plain,请求与称为一个额外的标头中发送Origin.Origin标头包含请求页面的来源(协议,域名和端口),以便服务器可以轻松确定它是否应该提供响应.示例Origin标头可能如下所示:

Origin: http://www.stackoverflow.com
Run Code Online (Sandbox Code Playgroud)

如果服务器决定应该允许该请求,它会发送一个Access-Control-Allow-Origin标头,回显发送的相同源或者*它是公共资源.例如:

Access-Control-Allow-Origin: http://www.stackoverflow.com
Run Code Online (Sandbox Code Playgroud)

如果缺少此标头,或者原点不匹配,则浏览器不允许该请求.如果一切顺利,则浏览器处理请求.请注意,请求和响应都不包含cookie信息.

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();
}
Run Code Online (Sandbox Code Playgroud)

请注意,要使CORS方法起作用,您需要访问任何类型的服务器标头机制,并且不能简单地访问任何第三方资源.

资料来源:http://www.nczonline.net/blog/2010/05/25/cross-domain-ajax-with-cross-origin-resource-sharing/

window.postMessage方法

  • 方法类型:iframe.

window.postMessage当被调用时,MessageEvent当任何必须执行的挂起脚本完成时(例如,window.postMessage从事件处理程序调用剩余的事件处理程序,先前设置的挂起超时等),导致在目标窗口调度a .的MessageEvent具有类型消息,data其被设置为提供到所述第一参数的字符串值属性window.postMessage,一个origin对应于窗口调用主文档的原点属性window.postMessage在时间window.postMessage被调用,并且一个source属性,该属性是窗口从这window.postMessage被称为.

要使用window.postMessage,必须附加事件侦听器:

    // Internet Explorer
    window.attachEvent('onmessage',receiveMessage);

    // Opera/Mozilla/Webkit
    window.addEventListener("message", receiveMessage, false);
Run Code Online (Sandbox Code Playgroud)

并且receiveMessage必须声明一个函数:

function receiveMessage(event)
{
    // do something with event.data;
}
Run Code Online (Sandbox Code Playgroud)

场外iframe还必须通过postMessage以下方式正确发送事件:

<script>window.parent.postMessage('foo','*')</script>
Run Code Online (Sandbox Code Playgroud)

任何窗口都可以在任何其他窗口上随时访问此方法,无论窗口中文档的位置如何,都可以向其发送消息.因此,用于接收消息的任何事件侦听器必须首先使用origin和可能的source属性检查消息发送者的身份.这不能低估:未检查origin和可能的source属性会启用跨站点脚本攻击.

资料来源:https://developer.mozilla.org/en/DOM/window.postMessage


Dan*_*llo 41

反向代理方法

  • 方法类型:Ajax

在服务器上设置简单的反向代理将允许浏览器使用Ajax请求的相对路径,而服务器将充当任何远程位置的代理.

如果在Apache中使用mod_proxy,则设置反向代理的基本配置指令是ProxyPass.它通常使用如下:

ProxyPass     /ajax/     http://other-domain.com/ajax/
Run Code Online (Sandbox Code Playgroud)

在这种情况下,浏览器将能够/ajax/web_service.xml作为相对URL 请求,但服务器将通过充当代理来服务于此http://other-domain.com/ajax/web_service.xml.

该方法的一个有趣特征是反向代理可以轻松地将请求分配给多个后端,从而充当负载平衡器.


Nic*_*not 17

我使用JSONP.

基本上,你添加

<script src="http://..../someData.js?callback=some_func"/>
Run Code Online (Sandbox Code Playgroud)

在你的页面上.

应该调用some_func(),以便通知您数据所在的位置.

  • JSONP有两个问题:a)您正在向目标域添加脚本标记.他们可以发回任何东西,甚至是常规的javascript(XSS攻击).所以你真的必须相信他们不要做坏事或被黑客攻击b)任何其他网页都可以添加相同的脚本标签,并窃取数据,所以永远不要将JSONP用于私人数据. (7认同)
  • @T-Bull:问题是JSONP无法进行正确的身份验证.用户登录站点A,然后转到站点B,站点B使用JSONP脚本标记从A加载数据.好,好.然后用户被欺骗访问邪恶站点C,它也使用JSONP脚本标记从A加载数据.因为用户通过A进行身份验证,C的所有者现在可以从A窃取用户数据.即使用户使用双因素身份验证进行A身份验证.问题是JSONP非常不安全.JSONP不是演示文稿.这是不安全的数据传输. (2认同)

rip*_*234 13

AnyOrigin在一些https网站上运行不佳,所以我写了一个名为whateverorigin.org的开源替代方案,似乎与https配合得很好.

github上的代码.


rk1*_*k1s 12

克服我发现的同源策略的最新方法是http://anyorigin.com/

该网站的制作是为了你只需给它任何网址,它为你生成javascript/jquery代码,让你获得html /数据,无论它是什么来源.换句话说,它使任何网址或网页成为JSONP请求.

我发现它非常有用:)

以下是来自anyorigin的一些示例javascript代码:

$.getJSON('http://anyorigin.com/get?url=google.com&callback=?', function(data){
    $('#output').html(data.contents);
});
Run Code Online (Sandbox Code Playgroud)

  • 这意味着:a)anyorigin将能够读取您通过tem传输的所有数据b)anyorigin可以XSS您的网站,读取您网站上的所有数据,并向您的用户传递恶意软件(如果anyorigin被黑客攻击会怎样?) (13认同)

Mat*_*fer 12

我不能声称这张图片,但它符合我在这个主题上所知道的一切,同时也提供了一些幽默.

http://www.flickr.com/photos/iluvrhinestones/5889370258/