未加星标

跨域方法总结

字体大小 | |
[前端(javascript) 所属分类 前端(javascript) | 发布者 店小二04 | 时间 2016 | 作者 红领巾 ] 0人收藏点击收藏

最近面试问的挺多的一个问题,就是javascript的跨域问题。在这里,对跨域的一些方法做个总结。由于浏览器的同源策略,不同域名、不同端口、不同协议都会构成跨域;但在实际的业务中,很多场景需要进行跨域传递信息,这样就催生出多种跨域方法。

1. 具备src的标签 原理:所有具有 src 属性的HTML标签都是可以跨域的

在浏览器中, <script> 、 <img> 、 <iframe> 和 <link> 这几个标签是可以加载跨域(非同源)的资源的,并且加载的方式其实相当于一次普通的GET请求,唯一不同的是,为了安全起见,浏览器不允许这种方式下对加载到的资源的读写操作,而只能使用标签本身应当具备的能力(比如脚本执行、样式应用等等)。

2. JSONP跨域 原理: <script> 是可以跨域的,而且在跨域脚本中可以直接回调当前脚本的函数

script标签是可以加载异域的JavaScript并执行的,通过预先设定好的callback函数来实现和母页面的交互。它有一个大名,叫做JSONP跨域,JSONP是JSON with Padding的略称。它是一个非官方的协议,明明是加载script,为啥和JSON扯上关系呢?原来就是这个callback函数,对它的使用有一个典型的方式,就是通过JSON来传参,即将JSON数据填充进回调函数,这就是JSONP的JSON+Padding的含义。JSONP只支持GET请求。

前端代码:

<script type="text/javascript">
function dosomething(jsondata){
//处理获得的json数据
}
</script>
<script src="http://haorooms.com/data.php?callback=dosomething"></script>

后台代码:

<php
$callback = $_GET['callback'];//得到回调函数名
$data = array('a','b','c');//要返回的数据
echo $callback.'('.json_encode($data).')';//输出
?>
3. 跨域资源共享(CORS) 原理:服务器设置Access-Control-Allow-Origin HTTP响应头之后,浏览器将会允许跨域请求

CORS是html5标准提出的跨域资源共享(Cross Origin Resource Share),支持GET、POST等所有HTTP请求。CORS需要服务器端设置 Access-Control-Allow-Origin 头,否则浏览器会因为安全策略拦截返回的信息。

Access-Control-Allow-Origin: * # 允许所有域名访问,或者
Access-Control-Allow-Origin: http://a.com # 只允许所有域名访问

CORS又分为简单跨域和非简单跨域请求,有关CORS的详细介绍请看 阮一峰 的 跨域资源共享 CORS 详解 ,里面讲解的非常详细。

4. document.domain 原理:相同主域名不同子域名下的页面,可以设置document.domain让它们同域

我们只需要在跨域的两个页面中设置document.domain就可以了。修改document.domain的方法只适用于不同子域的框架间的交互,要载入iframe页面。

例如:1. 在页面 http://a.example.com/a.html 设置document.domain

<iframe id = "iframe" src="http://b.example.com/b.html" onload = "test()"></iframe>
<script type="text/javascript">
document.domain = 'example.com';//设置成主域
function test(){
alert(document.getElementById('iframe').contentWindow);//contentWindow 可取得子窗口的 window 对象
}
</script>

2、在页面http:// b.example.com/b.html 中设置document.domain

<script type="text/javascript">
document.domain = 'example.com';//在iframe载入这个页面也设置document.domain,使之与主页面的document.domain相同
</script>
5. window.name 原理:window对象有个name属性,该属性有个特征:即在一个窗口(window)的生命周期内,窗口载入的所有的页面都是共享一个window.name的,每个页面对window.name都有读写的权限,window.name是持久存在一个窗口载入过的所有页面中的。

这里有三个页面:

sever.com/a.html 数据存放页面 agent.com/b.html 数据获取页面 agent.com/c.html 空页面,做代理使用

a.html中,设定 window.name 作为需要传递的值

<script>
window.name = 'I was there!';
alert(window.name);
</script>

b.html中,当iframe加载后将iframe的 src 指向同域的 c.html ,这样就可以利用 iframe.contentWindow.name 获取要传递的值了

<body>
<script type="text/javascript">
iframe = document.createElement('iframe');
iframe.style.display = 'none';
var state = 0;
iframe.onload = function() {
if(state === 1) {
var data = JSON.parse(iframe.contentWindow.name);
alert(data);
iframe.contentWindow.document.write('');
iframe.contentWindow.close();
document.body.removeChild(iframe);
} else if(state === 0) {
state = 1;
iframe.contentWindow.location = 'http://agent.com/c.html';
}
};
iframe.src = 'http://sever.com/a.html';
document.body.appendChild(iframe);
</script>
</body>

成功获取跨域数据,效果如下:


跨域方法总结
6. window.postMesage 原理: HTML5新增的postMessage方法,通过postMessage来传递信息,对方可以通过监听message事件来监听信息。可跨主域名及双向跨域。

这里有两个页面:

agent.com/index.html server.com/remote.html

本地代码index.html

<body>
<iframe id="proxy" src="http://server.com/remote.html" onload = "postMsg()" style="display: none" ></iframe>
<script type="text/javascript">
var obj = { msg: 'hello world'
}
function postMsg (){ var iframe = document.getElementById('proxy'); var win = iframe.contentWindow; win.postMessage(obj,'http://server.com');
}
</script>
</body>

本文前端(javascript)相关术语:javascript是什么意思 javascript下载 javascript权威指南 javascript基础教程 javascript 正则表达式 javascript设计模式 javascript高级程序设计 精通javascript javascript教程

分页:12
转载请注明
本文标题:跨域方法总结
本站链接:http://www.codesec.net/view/483829.html
分享请点击:


1.凡CodeSecTeam转载的文章,均出自其它媒体或其他官网介绍,目的在于传递更多的信息,并不代表本站赞同其观点和其真实性负责;
2.转载的文章仅代表原创作者观点,与本站无关。其原创性以及文中陈述文字和内容未经本站证实,本站对该文以及其中全部或者部分内容、文字的真实性、完整性、及时性,不作出任何保证或承若;
3.如本站转载稿涉及版权等问题,请作者及时联系本站,我们会及时处理。
登录后可拥有收藏文章、关注作者等权限...
技术大类 技术大类 | 前端(javascript) | 评论(0) | 阅读(32)