网络-9【六种跨域获取数据的方法】

一.基础引导

(1).通过Ifram获取数据

通过Ifram 的contentWindow获取index2.html数据

index1
<iframe src="index2.html" id="myIframe"></iframe>
<script type="text/javascript">
    var myIframe = document.getElementById('myIframe');
    myIframe.onload = function(){
        console.log(myIframe.contentWindow.name);
    }
</script>    
index2
<script type="text/javascript">
    window.name = 'iframeWindow';
</script>  

通过.parent来访问父元素的name,此时window指向Index2

index2
<script type="text/javascript">
    <iframe src="index3.html" id="myIframe"></iframe>
    window.name = 'iframeWindow';
    var iframe = document.getElementById('myIframe');
    iframe.onload = function(){
        console.log(window.parent.name)
    }
</script> 

通过.parent.parent来访问父元素的name,此时window指向Index3

index3
<script type="text/javascript">
        console.log(window.parent.parent.name)
</script> 

(2).window共享性

window是具有共享性的,在同一个窗口不同的页面是可以共享的 ,而且可以随意的读写

index1
<script type="text/javascript">
    window.name="window";
    location.href = "index2.html"
</script> 
index2
<script type="text/javascript">
    console.log(window.name)
</script> 

这样是会报错的,同源策略会限制iframe与window一致

index1
<iframe src="http://....index2.html" id="myIframe"></iframe>//不同源的地址
<script type="text/javascript">
    var myIframe = document.getElementById('myIframe');
    myIframe.onload = function(){
        console.log(myIframe.contentWindow.name);
    }
</script> 

二.跨域

(1).服务器中转

说明:同源策略只针对浏览器,所以服务器没有跨域限制

(2).设置基础域名+Iframe

说明:前提是基础域名必需一致

建立一个与接口同源的页面设置domain引入AJAX接口,再在主页面设置相同domain通过Iframe引入,此时就可以通过contentWindow获取到AJAX接口方法开始请求

index1
document.domain = "xxx.com";
var iframe = document.createElement('iframe');
iframe.src = "http://test.xxx.com/index.html";
iframe.id = "myIframe";
iframe.style.display = "none";
iframe.onload = function(){
    var $$ = document.getElementById('myIframe').contentWindow.$;
    $$.post('http://test.xxx.com/get.php',{status:1},function(data){})
}
document.body.appendChild(iframe);

index2
<script src ="utils.js"></script>
document.domain="xxx.com"

封装

var ajaxDomain =(function(){
    function createIframe(frameId, frameUrl){
        var frame = document.createElement('iframe');
        frame.src = frameUrl;
        frame.id = frameId;
        frame.style.display = 'none';
        return frame;
    }
    return function(opt){
        document.domain = opt.basicDomain;
        var frame = createIframe(opt.frameId,opt.frameUrl);
        frame.onload = function(){
            var $$ = document.getElementById(opt.frameId).contentWindow.$;
            $$.ajax({
                url:opt.url,
                type:opt.type,
                data:opt.data,
                success:opt.success,
                error:opt.error
            })
        }
        document.body.appendChild(iframe);
    }
})();

//调用
ajaxDomain({
    basicDomain:'xxx.com',
    frameUrl:'http://test.xxx.com/index.html',
    url:'http://test.xxx.com/get.php',
    type:'POST',
    data:{
        status:1
    },
    success:function(data){},
    error:function(data){}
})

(3).window.name+iframe

说明:先让iframe中的页面程序保存window.name,然后跳转与父级别窗口同源的另一个页面,父级页面可以从当前的iframe拿到该页面的window.name

window.name的特点:

  1. 每个浏览器窗口都有一个全局变量window(包含iframe的contentWindow)
  2. 每个window对象都有一个name属性(注意:一个窗口只有一个name属性)
  3. 该窗口被关闭前,所有页面共享一个name属性并拥有读写权限
  4. 无论该窗口在被关闭前,载入什么页面,都不会改变name值
  5. 存储约为2Mb字符串
  6. 如果父级窗口 地址源和iframe地址源不同,父级无法通过ifram.contentWindow.name获取值,但iframe内部不受该规则限制

index1:
var flag = false;
var iframe = document.createElement('iframe');
var getDatas = function(){
    if(flag){
        var data = iframe.contentWindow.name;
    }else{
        flag = true;
        setTimeOut(function(){
            iframe.contentWindow.loaction ='index2.html';//执行完后 就刷新再从头执行了,此代码块执行两次
        },500)
    }
}
iframe.src = 'http://xxx.com/index.html';
if(iframe.attachEvent){
    iframe.attachEvent('onload',getDatas);
}else{
    iframe.onload = getDatas;
}
document.body.appendChild(iframe);

index2:
空 与index1同源 //就是因为子集不受影响所以可以获得window.name
index3:
   $.ajax{.....,function(){
       window.name = JSON.stringify(data);
   }}

(4).Postmessage+iframe

不常用原因

  1. 伪造数据端漏洞
  2. xss攻击
  3. 兼容性问题

变量参数: otherWindow.postMessage(message,targetOrigin)

otherWindow:接收方的引用

message:要发送到接受方的数据

targetOrigin:接收方的源,还有必需要有监听的message事件

index1
<iframe src="http://text.xxx.com/index.html" id="iframe"></iframe>
<script type="text/javascript>
 window.onmessage = function(e){
     var e = e || window.event;
     console.log(JSON.parse(e.data));
 }
 
 index2
$.post('http://test.xxx.com/get.php',{status:1},function(data){
    window.name= JSON.stringify(data);
    windwo.parent.postMessage(JSON.stringIfy(data),'http://index1.html')
}) 

(5).Hash+iframe

基本原理:利用url的hash值#xxx来传递数据

基础工具:location.hash

index1
<button id= "btn"> 获取HASH</button>
<iframe src="http://test.xxx.com/index2.html#getCourses" id='cc' />
<script type="text/javascript">
    var oBtn = document.getElementById('btn');
    oBtn.onclick = function(){
        console.log(JSON.parse(decodeURI(location.hash.substring(1))))
    }
</script>
index 2
<iframe src="http://test2.xxx.com/index3.html" id="iframe" ></iframe>
var hash = location.hash.substring(1),
    iframe = document.getElementById('iframe');
switch(hash){
    case 'getCourses':
        $.post('htttp://xxx.com/get.php',{},function(){
            var str = JSON.stringify(data);
            iframe.src = "http://xxx.com/index3.html#"+str;
        })
}    

index3 与index1 同源
setTimeout(function(){
    parent.parent.location.hash = self.location.hash.substring(1);
},300)

(6).Cors跨域

“跨域资源共享”(Cross-origin resource sharing)

1.任意域名: header("Access-Control-Allow-Origin;*")

单域名: header("Access-Control-Allow-Origin;http://...")

多域名:

2.通知服务器在真正的请求中会采用那种HTTP方法

 header("Access-Control-Request-Methods;GET,POST")

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值