JavaScript跨域方式总结
Posted danew
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JavaScript跨域方式总结相关的知识,希望对你有一定的参考价值。
1. jsonp请求
jsonp的原理是利用 script 标签的跨域特性,可以不受限制地从其他域中加载资源,类似的标签还有 img。
缺点:只支持GET请求而不支持POST等其他类型的HTTP请求。
<script>
//回调函数,用来发送给 php服务器
function getData(data)
console.log(data);
//核心本质 就是后端服务器 返回一个函数调用 getData('js')
createJsonp();
function createJsonp()
const s = document.createElement('script');
s.src='http://localhost/data.php?callback=getData';
document.body.appendChild(s);
</script>
<?php
//跨域必须允许,后台说了管用
//header('Access-Control-Allow-Origin:*');
$receive=$_GET["callback"]; // 拿到回调函数,可以用来判断
$arr = [
[
'id'=>1,
'name'=>'追梦',
'age'=>18
],
[
'id'=>2,
'name'=>'阿飞',
'age'=>18
]
];
//编译成字符串
echo json_encode($arr);
?>
2. document.domain
这种方法用在主域名相同子域名不同的跨域访问中。举个例子:http://a.frame.com和http://b.frame.com 他们的主域名都是frame.com 这两个域名中的文件可以用这种方式进行访问,通过在两个域中具体的文件中设置document.domain="frame.com"就可达到跨域访问的目的。
实际应用中常常用在iframe中窗口之间的访问,根据浏览器的同源策略,浏览器中不同域的框架之间是不能进行js的交互操作的,所以一个窗口是不能拿到另一个窗口中的contentWindow对象的属性和方法的(注意是能拿到contentWindow对象的,只是属性和方法都不可用)。
为了能拿到数据,只要在两个iframe中分别写入document.domain="主域名",这样设置之后,就能拿到contentWindow对象的属性和方法了。
3. window.name
window的name属性有个特征:在一个窗口(window)的生命周期内,窗口载入的所有的页面都是共享一个window.name的,每个页面对window.name都有读写的权限,window.name是持久存在一个窗口在载入过的所有页面中的,并不会因新页面的载入而进行重置。
比如我在a.html这个页面中设置了window.name="a";然后让window重新加载b.html页面,然后在b.html页面中输出window.name会发现window.name=“a”。所以就算a.html和b.html这两个页面不是在同一个域中的,也可以在b页面中拿到a页面设置的window.name的值,跨域的核心思路就是这个原理。
例子:getDomainData.html是获取数据的页面,null.html是一个和getDomainData.html同域的空页面,它的作用是作为一个中转站,进行数据的过渡。data.html是要获取数据的所在页面,这里有着我们要的数据,它和getDomainData.html处于不同域中,所以取数据是跨域访问。
具体的过程是这样的:在getDomainData.html中建立一个子页面iframe,把这个iframe的src指向b.com/data.html,这样当这个iframe加载完成后就可以访问到data.html中的window.name的数据,之后再将iframe的src改为a.com/null.html,跳回getDomainData.html的同一个域,这样根据同源策略,getDomainData.html就可以访问到null.html中取得的data.html的数据了。获取数据以后最好销毁这个iframe,释放掉内存,也保证了安全。
getDomainData.html:
<script type="text/javascript">
var flag=0;
var data;
var iframe=document.createElement("iframe");//创建一个中转站iframe
document.appendChild(iframe);
getData=function() //iframe加载完成后调用的处理函数
if(flag==1)
data=iframe.contentWindow.name; //读取b.html中的window.name
else
flag=1;
iframe.src="http://a.com/null.html";//跳回getDomainData.html的同一个域
;
iframe.src="http://b.com/data.html";//设置src到要获得数据的域中的对应页面
if (iframe.attachEvent) //兼容IE,监听iframe加载完成
iframe.attachEvent('onload', getData);
else
iframe.addEventListener('load',getData);
</script>
data.html:
<script>
window.name="被获取数据"//简单的一行代码
</script>
最后的iframe销毁:
<script>
iframe.contentWindow.document.write(""); //情况iframe中的内容
iframe.contentWindow.close(); //避免iframe的内存泄漏
document.body.removeChild(iframe); //移除iframe节点
</script>
4. window.postMessage
window.postMessage是html5中实现跨域访问的一种新方式,可以使用它来向其它的window对象发送消息,无论这个window对象是否属于同源或不同源。
5. CORS
使用自定义的HTTP头部让浏览器与服务器进行沟通,从而决定请求或响应是应该成功还是应该失败。
6. Web Sockets
在js创建了web socket之后,会有一个HTTP请求发送到浏览器以发起连接。取得服务器响应后,建立的连接会使用HTTP升级从HTTP协议交换为web socket协议。
详情参见大佬总结:https://segmentfault.com/a/1190000008525104
以上是关于JavaScript跨域方式总结的主要内容,如果未能解决你的问题,请参考以下文章