跨域
跨域是指从一个域请求另一个域的资源。跨域是由于浏览器的同源策略导致的,跨域限制主要是为了用户信息的安全考虑,防止恶意网站窃取数据
只要协议、域名、端口其中的一个不同,都会被当成不一样的域,之间的相互请求就是跨域。
- DOM同源策略:禁止对不同页面的DOM进行操作,主要场景是iframe跨域请求,不同域的iframe之间限制访问
- XMLHttpRequest同源策略:禁止使用不同的XHR对象向不同源的服务器地址发送http请求
解决方法
1.跨域资源共享(CORS)
推荐阮一峰跨域资源共享CORS
CORS跨域资源请求分为简单请求和非简单请求
-
简单请求
简单请求必须同时满足以下两个条件
(1)请求方式必须是以下三种- post
- get
- head
(2)HTTP的头部信息不能超出以下字段
- Accept
- Accept-Language
- Conten-Language
- Last-Event-ID
- Content-Type //只限于三个值application/x-www-form-urlencoded、multipart/form-data、text/plain
-
非简单请求
凡是不同时满足以上两个条件的都成为非简单请求
非简单请求会在正式通信之前增加一次HTTP查询请求,成为“预检”请求,通过预检请求之后,以后的每次请求就像简单请求一样
2.JSONP
原理是动态插入
<script>
标签,通过<script>
标签动态引入一个js
文件,文件载入成功后就会执行url
中传递的函数,并且会把我们需要的json
数据作为参数传入。但是JSONP
的缺点就是适合于GET请求。
3.设置document.domain
共享cookie
cookie
是服务器写入浏览器的一小段信息,只有同源的网页才能共享。但是两个网页一级域名相同,只是二级域名不相同,浏览器就允许通过设置document.domain
来共享cookie
- 但是这种方法只适用于
cookie
和iframe
。LocalStorage
和IndexDB
无法通过这种方法规避同源政策 - 一个页面框架(iframe/frame)之间(包括父子或同辈),能够获取彼此的window对象,但是这个window对象不能获取方法和属性
4.使用window.name
进行跨域
浏览器窗口有
window.name
属性,这个属性的最大的特点就是:在一个窗口的生命周期内,窗口载入的所有页面都共享一个window.name
,每个页面都对它有读写的权利,window.name
是持久的存在于窗口载入的所有页面中的,不会因为新的窗口的载入而被重置。
window.name
的容量很大,可以放置很长的字符串
5.使用postMessage
进行跨域
HTML5引入了一个跨文档通信API,这个API为
window
对象新增了一个window.postMessage
方法,允许垮窗口通信,不论这两个窗口是否同源
比如:父窗口http://a.com
向子窗口http://b.com
发消息,只需调用postMessage
方法
var p = window.open("http://b.com","title");
p.postMessage("hello","http://b.com");
postMessage
的第一个参数是需要传递的具体信息内容,第二个参数是接收消息窗口的源。也可以设为“*”
,表示不限制域名,可以向所有窗口发送。