说说跨域那些事儿(转载)

原文链接:http://itoss.me/2016/12/31/说说跨域那些事儿/

作者寄语:首先纠正一个误区,跨域并非浏览器限制了发起跨站请求的这种能力,恰恰相反,我们可以发出请求,服务端也可以接收到请求并正常返回数据,只不过在返回之后浏览器会阻止非同源数据(response),从而在控制台打出一系列报错信息。
兼容性查找

文章中会涉及一系列兼容性的图解(mdn & can i use)和一些专有名词(mdn),可以通过两个渠道来查看

Can I Use
MDN
什么是跨域

定义就不说了,从字面也可以看其含义,首先我们认识下哪些情况属于跨域,可以分为以下几点:

协议不同,如http, https;
端口不同;
主域相同,子域不同;
主域不同;
ip地址和域名之间也算是跨域,浏览器不会自动做ip域名的映射;
解决方案

document.domain
window.name
jsonp
postMessage
cors
document.domain

关键点
跨域分为两种,一种xhr不能访问不同源的文档,另一种是不同window之间不能进行交互操作;
document.domain主要是解决第二种情况,且只能适用于主域相同子域不同的情况;
document.domain的设置是有限制的,我们只能把document.domain设置成自身或更高一级的父域,且主域必须相同。例如:a.b.example.com中某个文档的document.domain可以设成a.b.example.com、b.example.com 、example.com中的任意一个,但是不可以设成c.a.b.example.com,因为这是当前域的子域,也不可以设成baidu.com,因为主域已经不相同了。
兼容性:所有浏览器都支持;
优点:
可以实现不同window之间的相互访问和操作;
缺点:
只适用于父子window之间的通信,不能用于xhr;
只能在主域相同且子域不同的情况下使用;
使用方式
a(当前页面或父页面)页面中加入document.domain = ‘example.com’;
b(当前页面或子页面)页面中加入document.domain = ‘example.com’;
a页面访问b页面里面的数据或者方法;
window.name

关键点:window.name在页面的生命周期里共享一个window.name;
兼容性:所有浏览器都支持;
优点:
最简单的利用了浏览器的特性来做到不同域之间的数据传递;
不需要前端和后端的特殊配制;
缺点:
大小限制:window.name最大size是2M左右,不同浏览器中会有不同约定;
安全性:当前页面所有window都可以修改,很不安全;
数据类型:传递数据只能限于字符串,如果是对象或者其他会自动被转化为字符串,如下;
window.name非字符串测试
使用方式:修改window.name的值即可;
jsonp

关键点:浏览器对XHR做了同源策略,但并没有将这种方式延续到script上(其实还有iframe,img等),从而可以利用动态script标签技术来做到跨域请求的作用。至于为什么会这样设计,本人也不太清楚,有可能是历史遗迹(漏洞),有可能是某些方面的技术瓶颈,也有可能是为了满足某些需求专门定制的,总之这项技术方案我们过去可以用,现在可以用就ok,至于将来应该也是会存在的,毕竟现在已经应用在很多家站点上,就算会废弃,也会有一段时间迭代。
兼容性:所有浏览器都兼容这种方式;
优点:很明显前端可以很轻松的做到跨域请求;
缺点
只能通过GET方式请求,一方面是参数长度有限制,二是安全性比较差;
后端需要知道前端的cb是什么样的结构,主要在参数和回调名;
后端需要进行参数和cb的拼接然后才能执行;
使用方式
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/* 前端生成script标签,并将src中传入需要执行的callback */

var ele = document.createElement('script'); ele.type = "text/javascript" ele.src = "http://example.com?jsonp=cb"; document.body.appendChild(ele);

/* 后端接到参数后给callback加入参数并执行 */

发布了25 篇原创文章 · 获赞 10 · 访问量 15万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章