Javascript 规避同一原产地政策的方法 同一原产地政策

Javascript 规避同一原产地政策的方法 同一原产地政策,javascript,ajax,same-origin-policy,Javascript,Ajax,Same Origin Policy,我想制作一个关于HTML/JS同源策略的社区wiki,希望能帮助搜索此主题的任何人。这是搜索最多的SO主题之一,没有整合的wiki,因此我决定: 同一原产地政策可防止 从一个数据库加载的文档或脚本 起源于获得或设置 来自另一个文档的文档属性 起源这项政策一直沿用至今 回到Netscape Navigator 2.0 您最喜欢采用哪些方法来执行相同的原产地政策? 请保持示例的详细性,最好同时链接您的源代码。就我个人而言,window.postMessage是我为现代浏览器找到的最可靠的方式。您确实

我想制作一个关于HTML/JS同源策略的社区wiki,希望能帮助搜索此主题的任何人。这是搜索最多的SO主题之一,没有整合的wiki,因此我决定:

同一原产地政策可防止 从一个数据库加载的文档或脚本 起源于获得或设置 来自另一个文档的文档属性 起源这项政策一直沿用至今 回到Netscape Navigator 2.0

您最喜欢采用哪些方法来执行相同的原产地政策? 请保持示例的详细性,最好同时链接您的源代码。

就我个人而言,window.postMessage是我为现代浏览器找到的最可靠的方式。您确实需要做更多的工作来确保自己不会受到XSS攻击,但这是一个合理的权衡

还有一些流行的Javascript工具包的插件,它们包装window.postMessage,使用上面讨论的其他方法提供与旧浏览器类似的功能。

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

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

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

这种方法的一个有趣的特性是,反向代理可以很容易地将请求分发到多个后端,从而充当一个代理

我使用JSONP

基本上,你加上

<script src="http://..../someData.js?callback=some_func"/>
在你的页面上

应该调用某些函数,以便通知您数据在document.domain方法中。

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

document.domain = "company.com";
在该语句执行之后,页面将通过带有http://company.com/dir/page.html. 但是,基于同样的理由,company.com无法将document.domain设置为othercompany.com

使用此方法,您可以从源于主域的页面上的子域上的iframe执行javascript。此方法不适用于跨域资源,因为Firefox等浏览器不允许您将document.domain更改为完全陌生的域

资料来源:

跨源资源共享方法 方法类型:AJAX。 CORS是一个W3C工作草案,定义了在跨源访问源时浏览器和服务器必须如何通信。CORS背后的基本思想是使用自定义HTTP头,使浏览器和服务器都能够充分了解彼此,以确定请求或响应是成功还是失败

对于一个简单的请求,一个使用GET或POST且没有自定义头的请求,其主体是text/plain,该请求将与一个名为Origin的额外头一起发送。Origin头包含请求页面的Origin协议、域名和端口,以便服务器可以轻松确定是否应该提供响应。示例原点标头可能如下所示:

Origin: http://www.stackoverflow.com
如果服务器决定应该允许该请求,它将发送一个访问控制允许源报头,回显已发送的相同源或*如果是公共资源。例如:

Access-Control-Allow-Origin: http://www.stackoverflow.com
如果缺少此标头,或者来源不匹配,则浏览器不允许该请求。如果一切正常,浏览器将处理该请求。请注意,请求和响应都不包含cookie信息

Mozilla团队建议您检查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();
}
请注意,要使CORS方法工作,您需要访问任何类型的服务器头机制,并且不能简单地访问任何第三方资源

资料来源:

window.postMessage方法 方法类型:iframe。 调用window.postMessage时,当必须执行的任何挂起脚本完成时,会导致MessageEvent在目标窗口中调度,例如,如果从事件处理程序调用window.postMessage,则剩余的事件处理程序、以前设置的挂起超时等。。MessageEvent的类型为message,这是一个数据属性,设置为window.postMessage的第一个参数的字符串值,这是一个源属性 对应于调用window.postMessage时调用window.postMessage的窗口中主文档的来源,以及调用window.postMessage的窗口的源属性

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

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

    // Opera/Mozilla/Webkit
    window.addEventListener("message", receiveMessage, false);
并且必须声明receiveMessage函数:

function receiveMessage(event)
{
    // do something with event.data;
}
非现场iframe还必须通过postMessage正确发送事件:

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

来源:

我想到的是:

JSONP或带填充的JSON是 对基本JSON数据的补充 格式,一种允许 一页一页的请求,更有意义 从服务器以外的服务器使用JSON 主服务器。JSONP是一个 一种较新方法的替代方法 称为跨源资源共享


我在PHP中使用了curl来避免这种情况。我有一个Web服务在端口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;

?>

我的HTML在端口80的WAMP上运行。因此,我们就这样做了,同一原产地政策被规避了:-

我发现的克服同一原产地政策的最新方法是

该站点的创建使得您只需给它任何url,它就会为您生成javascript/jquery代码,让您可以获取html/数据,而不管其来源如何。换句话说,它使任何url或网页成为JSONP请求

我发现它非常有用:

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

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

AnyOrigin在一些https站点上运行不好,所以我只编写了一个开源的替代方案,名为,它似乎可以很好地使用https


.

我不能说这张图片值得称赞,但它符合我对这一主题的所有了解,同时也提供了一点幽默感


以下是一些解决办法和对同源策略的解释:

这篇文章大致分析了市场上的可用信息:

有关postMessage解决方案,请查看:

还有一个稍微不同的版本:


好主意。。你应该把你的例子写进答案中;就目前情况而言,它们使问题变得相当庞大。您还应该为每种方法添加一个安全影响列表。JSONP对于私有数据是高度不安全的。为什么关闭?在过去的两年里,这个维基问题非常有用。此外,许多答案都有参考文献支持。一个不具建设性的标签似乎完全没有意义,因此,一个解释将是值得赞赏的。投票赞成重新开放。我希望我得到答案不会太晚:唯一的问题是,localhost总是一个例外吗?总是不允许吗?我应该停止通过本地主机进行测试吗?我不知道为什么,但当我设置:Access Control Allow Origin:http://www.stackoverflow.com/ 而不是:访问控制允许原点:http://www.stackoverflow.com 在url的末尾斜杠,它在Safari和FF中不起作用,但在Chrome中起作用。当然,不使用斜杠在所有浏览器中都可以正常工作。也许值得让人们知道,postMessage方法只适用于支持它的浏览器,因为它是HTML5的补充。试图解释这一点。提到这一点是因为我学到了这一点。虽然这给了我一些关于https站点的问题,但请查看下面我的开源替代方案:这意味着:a anyorigin将能够读取通过tem传输的所有数据b anyorigin可以XSS您的站点,读取您站点上的所有数据,并将恶意软件发送给用户如果anyorigin被黑客攻击会发生什么?@Erlend-fork Whateverorigin并将其托管在您自己的服务器上。代码很简单,所以你可以检查它以确保没有隐藏漏洞。@DavidItarenco-它让我疯狂地试图理解任何来源的肚子里发生的一些事情。幸运的是,我发现一篇博文很有帮助,现在下一个家伙如果需要的话,将会有一个工作的测试站点。@neoascetic-修复了用法。。。现在需要对URL进行编码。JSONP有两个问题:一个是您正在向目标域添加脚本标记。他们可以发送任何东西,甚至是常规的javascript XSS攻击。因此,你必须相信他们不会做坏事或被黑客攻击。任何其他网页都可以添加相同的脚本标记并窃取数据,因此永远不要将JSONP用于私有数据。@Erlend:除非需要正确的身份验证,否则任何人都可以检索web上提供的任何信息。信息呈现的确切格式并不能使其更好或更糟,即使是JSONP。@T-Bull:问题是JSONP不可能进行正确的身份验证。用户登录站点A,然后转到站点B,站点B使用JSONP脚本标记从A加载数据。一切都很好。然后用户被诱骗进入visi
它还使用JSONP脚本标记从a加载数据。因此,由于用户使用a进行身份验证,C的所有者现在可以从a窃取用户数据。即使用户使用双因素身份验证从a进行身份验证,也是如此。问题是JSONP是高度不安全的。JSONP并不是一个演示。这是不安全的数据传输。JSONP只支持HTTP GET。这代表什么.js文件->http://..../someData.js....I'我试图从另一个站点客户端读取dom,需要绕过同源策略。请参阅我对上面JSONP的评论。这不是私有数据的好选择。
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();
}
$.getJSON('http://anyorigin.com/get?url=google.com&callback=?', function(data){
    $('#output').html(data.contents);
});