前端跨域策略

假设页面http://www.example.com/a.htmlhttp://www.example.com/b.html属于不同域,a页面请求b页面的内容.

document.domain

利用document.domain实现跨域的前提是这两个域名必须属于同一个基础域名,协议端口都要一致。主要是父域和子域之间的通信

  • 如aaa.com下的网页a.html通过iframe引用bbb.com下的网页b.html,这时a.html里面能看到b.html的内容,但不能用JS操作它,因为属于不同域。

  • 另一种情况:两个子域名aaa.xxx.com和bbb.xxx.com,aaa.xxx.com下的网页a.html通过iframe引用bbb.xxx.com下的网页b.html,仍不能操作因为域名不同,此时可将这两个页面的domain改为一样的document.domain="xxx.com"这就实现了同一基础域名之间的跨域。

  • 将b页面通过iframe引入a页面,也可将其隐藏,在两个页面中的script 中将document.domain设置成两页面公共的父级域名example.com,如果两页面都是本地载入的,可用localhost。按以下引用b页面: 
    var iframe = document.getElementById("iframe"); 
    var bDocument = iframe.contentDocument; 
    此时bDocument 即是b页面的document对象,可引用b页面的内容;

window.name

  • 从一个窗口下打开的另一个页面和父窗口拥有相同的window.name值
  • window.name是当前窗口的名字,每个iframe都有包裹他的window,这个window 也有他自己的window.name,
  • window.name的值在不同页面加载后依然存在,未修改值不变(2MB)。
  • 假设index.html要请求服务器上的数据:在index.html页面下:

    iframe=document.getElementById("iframe");
    iframe.src='http://localhost:8080/data.php';
    iframe.onload=function(){console.log(iframe.contentWindow.name)}
    

    然而由于要求协议主机端口必须一致才能请求,因此此时已经跨域了,由于window.name的值保持不变,可在index.html页面相同目录中新建proxy.html:

     iframe.onload=function(){
         iframe.src='http://localhost:8181/proxy.html';
        console.log(iframe.contentWindow.name)
    }
       
       
    • 1
    • 2
    • 3
    • 4

    此时虽然能正确得到window.name的值,但是由于每次iframe.src的加载都执行iframe.onload,循环执行,页面循环刷新,解决办法:

    iframe.style.display='none';
    var state=0;
    iframe.onload=function(){
        if(state===1){
            console.log(iframe.contentWindow.name);
            document.body.removeChild(iframe)
        }else{
            state=1;
        iframe.contentWindow.location='http://localhost:8181/proxy.html';
        }
    }
    iframe.src='http://localhost:8080/data.php';
    document.body.a(iframe)
       
       
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    将要从b页面获取的值设置成b的 window.name,然后从b页面载入a页面window.locattion='http://www.example.com/a.html',同样获取window.name,即是b页面设置的值。 
    原理:iframe的跨域能力及window.name在页面刷新后依旧存在。

H5的window.postMessage(实时通信)

postMessage(data,origin)

data表示要传递的数据,部分浏览器只能处理字符串参数,可用JSON.stringify将对象序列化。 
origion:目标窗口的源,协议主机端口号,也可设为*,即传递给任意窗口。

http://test.com/index.html,在index.html中,主页面向iframe发送请求:

window.onload=function(){
window.frames[0].postMessage('getcolor','http://lslib.com')
}
//主页面接受iframe传来的消息
window.addEventListener('message',function(e){
console.log(e.data);
})

lsLib.html:

//iframe接受消息,向主页面反馈信息:

window.addEventListener('message',function(e){
    if(e.source!=widow.parent) return;
        window.parent.postMessage('someinfor come from iframe','*')
},false);

jsonp(从服务器获取数据,兼容性好)

要获取不同域上的json对象,假设http://www.example.com/data.php为a.html页面不同域上的json对象。要在a中引用data.php里面返回的数据可在a中这样写:

function dosomething(data){
//处理获取到的data
}

也可以用jQuery封装好的函数:

$.getJSON("http://www.example.com/data.php?callback=?",function(data){
//处理获取到的data
})

以上原文地址

针对JSONP的另一个例子

function handleResponse(response){
console.log(response.ip,response.city);}
var script = document.createElement('script');
script.src = "http://freegeoip.net/json/?callback=handleResponse";
document.head.a(script);

输出:210.74.131.196 ,因为http://freegeoip.net/json/的页面内容是:

{"ip":"210.74.131.196","country_code":"CN","country_name":"China","region_code":"","region_name":"","city":"","zip_code":"","time_zone":"","latitude":34.7725,"longitude":113.7266,"metro_code":0}

然而jsonp跨域可能造成XSS攻击,因此客户端接收callback参数时,若其中包含恶意标签(script)则可能存在风险,解决办法在服务器端用encodeURI对callback参数进行编码,客户端再用decodeURIComponent解码。

JSONP缺点分析

  • 只支持GET请求,不支持其他http method方法
  • 返回出错的话也不会提示错误的状态码
  • 只支持跨域HTTP请求,不支持两个页面的JavaScript互相调用问题
  • 存在注入攻击,则调用这个资源的页面都会受到影响

图像Ping

与服务器进行简单单向通信,一个网页可以加载任意网页上的图片

CORS(cross origin resource share)

定义一种跨域资源访问机制,基本思想是服务器发送一个HTTP响应表头

假设www.a.com要从www.b.com上请求数据。因为跨域所以响应失败,可在www.b.com中添header('Access-Control-Allow-Origin:www.a.com')则可接受www.a.com的请求,header('Access-Control-Allow-Origin:*')表示接受所有请求

总结

  • iframe缺点:阻止主页面的Onload事件,搜索引擎程序无法解读这种页面,不利于SEO(search engine optimization),会影响页面的并行加载(同一时间针对同一域名下的请求,各浏览器不同)。 
    • 解决方法,可在js中动态设置其src属性。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值