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.comhttp://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跨域方式总结的主要内容,如果未能解决你的问题,请参考以下文章

JavaScrip继承图文总结

JavaScript跨域总结与解决办法

JavaScript 跨域总结与解决办法giserdqy.com

JavaScript跨域总结与解决办法

JavaScript跨域总结与解决办法(转)

牛客网面试题总结