什么是同源
- 协议相同
- 域名相同
- 端口相同(实际上,同一网域不同端口,可以相互读取 Cookie)
同源限制范围
如果非同源,共有三个行为受到限制
(1)无法读取非同源网页的 Cookie、LocalStorage 和 IndexedDB
(2)无法接触非同源网页的 DOM
(3)无法向非同源地址发送 AJAX 请求(可以发送,但是浏览器拒绝接受响应)
Cookie
Cookie 是服务器写入浏览器的一小段信息,只有同源的网页才能共享。如果两个网页一级域名相同,只是次级域名不同,浏览器允许通过设置 document.domain
共享 Cookie
iframe 和多窗口通信
只有在同源的情况下,父窗口和子窗口才能通信;如果跨域,就无法拿到对方的 DOM
对于完全不同源的网站,目前有两种方法,可以解决跨域窗口的通信问题
- 片段识别符
- 跨文档通信 API
### 片段识别符
片段识别符指的是,URL 的 # 号后面的部分。父窗口把所要传递的信息,写入 iframe 窗口的片段标识符。
子窗口通过监听 hashchange
事件得到通知
postMessage
跨文档通信 API,允许跨窗口通信,不论这两个窗口是否同源。
// 父窗口打开一个子窗口
var popup = window.open('http://bbb.com', 'title');
// 父窗口向子窗口发消息
popup.postMessage('Hello World', 'http://bbb.com');
子窗口向父窗口发送信息的写法类似
window.opener.postMessage('Nice to see you', 'http://aaa.com')
父窗口和子窗口都可以通过 message
事件,监听到对方的消息
// 父窗口和子窗口都可以用下面的代码
//监听 message 消息
window.addEventListener('message', function (e) {
console.log(e.data)
}, false)
AJAX
同源策略规定,AJAX 请求只能发给同源的网址,否则就报错
有四种方法规避这种限制
JSONP
WebSocket
CORS
架设服务器代理 (浏览器请求同源服务器,再由后者请求外部服务)
JSONP
JSONP 最大特点是简单易用,没有兼容性问题
操作流程:
1.网页添加一个 <script>
元素,向服务器请求一个脚本,这不受同源政策限制,可以跨域请求
<script src="http://api.foo.com?callback=bar"></script>
请求网址有一个 callback
参数,用来告诉服务器,客户端的回调函数名称(bar)
2.服务器收到请求后,拼接一个字符串,将 JSON 数据放在函数名里面,作为字符串返回
3.客户端会将服务器返回的字符串,作为代码解析,因为浏览器认为,这是 <script>
标签请求的脚本内容。这时,客户端只要定义 bar()
函数,就能在该函数体内,获得服务器返回的 JSON 数据以下是动态插入 <script>
请求的例子
function addScriptTag(src) {
var script = document.createElement('script');
script.setAttribute('type', 'text/javascript');
script.src = src;
document.body.appendChild(script);
}
window.onload = function () {
addScriptTag('http://example.com/ip?callback=foo')
}
function foo(data) {
console.log('Your public IP address is: ' + data.ip)
}
WebSocket
WebSocket 是一种通信协议,使用 ws://
(非加密) 和 wss://
(加密)作为协议前缀。该协议不实行同源策略,只要服务器支持,就可以通过它进行跨域通信
CORS
CORS 是跨域资源共享,它是 W3C 标准,属于跨源 AJAX 请求的根本解决方法。相比 JSONP 只能发 GET 请求,CORS 可以发送任何请求
必须 注册 为本站用户, 登录 后才可以发表评论!