跨域
跨域通信的方式
- JSONP
- CORS
- Hash
- postMessage
- WebSoket
同源策略
- 端口相同
- 域名相同
- 协议相同
例子:http://www.example.com/dir/page.html
这个网址,协议是http
,域名是www.example.com
,端口是80
同源政策的目的,是为了保证用户信息的安全,防止恶意的网站窃取数据。是浏览器做的努力
同源策略限制范围
- Cookie、LocalStorage 和 IndexDB 无法读取
- DOM 无法获得
- AJAX 请求不能发送
CROS跨域资源请求
CORS(Cross-origin resource sharing)跨域资源请求
浏览器在请求一个跨域资源的时候,如果是跨域的Ajax请求,他会在请求头中加一个origin
字段,但他是不知道这个资源服务端是否允许跨域请求的。浏览器会发送到服务端,如果服务器返回的头中没有'Access-Control-Allow-Origin': '对应网址或 * '
的话,那么浏览器就会把请求内容给忽略掉,并且在控制台报错
CORS限制
允许的请求方法
- GET
- POST
- HEAD
允许的Content-Type
- text/plain
- multipart/form-data
- application/x-www-form-ulencoded
其他类型的请求方法和Content-Type需要通过预请求验证后然后才能发送
CORS预请求
跨域资源共享标准新增了一组 HTTP 首部字段,允许服务器声明哪些源站有权限访问哪些资源。另外,规范要求,对那些可能对服务器数据产生副作用的 HTTP 请求方法(特别是 GET 以外的 HTTP 请求,或者搭配某些 MIME 类型的 POST 请求),浏览器必须首先使用 OPTIONS 方法发起一个预检请求。
服务器在HTTP header中加入允许请求的方法和Content-Type后,其他指定的方法和Content-Type就可以成功请求了
1 | 'Access-Control-Allow-Headers': '允许Content-Type' |
JSONP跨域
浏览器上虽然有同源限制,但是像 srcipt标签、link标签、img标签、iframe标签,这种在标签上通过src地址来加载一些内容的时候浏览器是允许进行跨域请求的。
所以JSONP的原理就是:
- 创建一个script标签,这个script标签的src就是请求的地址;
- 这个script标签插入到DOM中,浏览器就根据src地址访问服务器资源
- 返回的资源是一个文本,但是因为是在script标签中,浏览器会执行它
- 而这个文本恰好是函数调用的形式,即函数名(数据),浏览器会把它当作JS代码来执行即调用这个函数
- 只要提前约定好这个函数名,并且这个函数存在于window对象中,就可以把数据传递给处理函数。
Hash值跨域通信
背景:在页面A下提供iframe或frame嵌入了跨域的页面B
容器页面 -> 嵌入页通信:
在A页面中改变B的url中的hash值,B不会刷新,但是B可以用过window.onhashchange
事件监听到hash变化
postMessage通信
1 | // 窗口A中 |
WebSoket 跨域通信
1 | var ws = new WebSocket('wss://echo.websoket.org') //这个是后端端口 |
document.domain
该方式只能用于二级域名相同的情况下,比如 a.test.com 和 b.test.com 适用于该方式。
只需要给页面添加 document.domain = ‘test.com’ 表示二级域名都相同就可以实现跨域