原文链接: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加入参数并执行 */
新闻热点
疑难解答