资讯专栏INFORMATION COLUMN

JavaScript跨域方式

Cciradih / 1204人阅读

摘要:跨域原因同源策略在客户端编程语言中,如和,同源策略是一个很重要的安全理念,它在保证数据的安全性方面有着重要的意义。同源策略规定跨域之间的脚本是隔离的,一个域的脚本不能访问和操作另外一个域的绝大部分属性和方法。由两部分组成回调函数和数据。

1.JavaScript跨域原因--同源策略

在客户端编程语言中,如javascript和 ActionScript,同源策略是一个很重要的安全理念,它在保证数据的安全性方面有着重要的意义。同源策略规定跨域之间的脚本是隔离的,一个域的脚本不能访问和操作另外一个域的绝大部分属性和方法。那么什么叫相同域,什么叫不同的域呢?当两个域具有相同的协议(如http), 相同的端口(如80),相同的host(如www.example.org),那么我们就可以认为它们是相同的域。比如 http://www.example.org/index....和http://www.example.org/sub/in...是同域,而http://www.example.org, https://www.example.org, http://www.example.org:8080, http://sub.example.org中的任何两个都将构成跨域。同源策略还应该对一些特殊情况做处理,比如限制file协议下脚本的访问权限。本地的HTML文件在浏览器中是通过file协议打开的,如果脚本能通过file协议访问到硬盘上其它任意文件,就会出现安全隐患,目前IE8还有这样的隐患。

由于JavaScript同源策略的限制,跨域资源共享就会受到制约:a.com域名下的js无法访问b.com或c.a.com下的对象,虽然保证了安全,但是给注入iframe和AJAX应用带来麻烦。跨域的限制具体表现为:

注意:只有协议、域名、端口号完全一样才是同一域,其他情况,即使是相对应的IP和域名也是不同域。

解决跨域问题的方式 单向跨域 JSONP、window.name、server proxy 双向跨域 document.domain、window.postMessage 后端方法

:https://developer.yahoo.com/j...

server proxy

在数据提供方没有提供对JSONP协议或者 window.name协议的支持,也没有对其它域开放访问权限时,我们可以通过server proxy的方式来抓取数据。例如当www.a.com域下的页面需要请求www.b.com下的资源文件asset.txt时,直接发送一个指向 www.b.com/asset.txt的Ajax请求肯定是会被浏览器阻止。这时,我们在www.a.com下配一个代理,然后把Ajax请求绑定到这个代理路径下,例如www.a.com/proxy/, 然后这个代理发送HTTP请求访问www.b.com下的asset.txt,跨域的HTTP请求是在服务器端进行的,客户端并没有产生跨域的Ajax请求。这个跨域方式不需要和目标资源签订协议,带有侵略性,另外需要注意的是实践中应该对这个代理实施一定程度的保护,比如限制他人使用或者使用频率。

前端方法: 方法1 document.domain+iframe

适用于:主域相同而子域不同(二级域名相同、协议相同、端口相同)。
具体的做法是可以在http://www.a.com/a.html和http://script.a.com/b.html两个文件中分别加上document.domain = ‘a.com’;然后通过a.html文件中创建一个iframe,去控制iframe的contentDocument,这样两个js文件之间就可以“交互”了。

    
    //www.a.com上的a.html
    document.domain = "a.com";
    var ifr = document.createElement("iframe");//创建子框架
    ifr.src = "http://script.a.com/b.html"; //子框架指向b.html
    ifr.style.display = "none";
    document.body.appendChild(ifr);
    ifr.onload = function(){
        //定义指针指向子框架内容的文档对象, 跨浏览器兼容
        var doc = ifr.contentDocument || ifr.contentWindow.document;
        // 获得子框架的文档对象之后在这里操纵b.html
        alert(doc.getElementsByTagName("h1")[0].childNodes[0].nodeValue);
    };

注意:除IE外的四大浏览器支持contentDocument属性,IE8以下只支持contentWindow对象,这个对象具有document属性,这个属性的效果和contentDocument属性一致。

    //script.a.com上的b.html
    document.domain = "a.com";

问题:

1、安全性,当一个站点(b.a.com)被攻击后,另一个站点(c.a.com)会引起安全漏洞。
2、如果一个页面中引入多个iframe,要想能够操作所有iframe,必须都得设置相同domain。
方法2: 跨文档消息传递 cross-document messaging,XDM(HTML5新增)

适用:这个方法非常强大,无视协议,端口,域名的不同。

otherWindow.postMessage(message, targetOrigin);
参数: otherWindow: 对接收信息页面的window的引用。可以是:页面中iframe的 contentWindow属性;window.open的返回值;通过name或下标从window.frames取到的值。

message: 所要发送的数据,string类型。
targetOrigin: 用于限制otherWindow,“*”表示不作限制

a.com/index.html中的代码:



b.com/index.html中的代码:


方法3 JSONP(JSON with padding)

原理:使用

阅读需要支付1元查看
<