第一部分:同源策略:same-origin policy
1.同源策略的由来:
1995年,同源策略由Netscape(曾经的浏览器霸主,拒绝微软收购请求,被IE给整垮。现在发展为火狐浏览器背后的Mozilla)引入。目前,所有浏览器都遵循同源策略。
2.同源定义:即同协议、同域名、同端口号
例如::80/test.html; 协议:http;域名:;端口号:80(默认端口,可以省略)
(同源)
test.com/test100.html (不同源,域名不同)
x./test100.html (不同源,域名不同)
:81/test100.html (不同源,端口号不同)
https://www.test.com/test100.html (不同源,协议不同)
但是在IE浏览器上端口号不同被认为是同源
截图自MDN,链接
3.同源策略目的:
防止其它网站恶意窃取数据。
例如: 假设没有同源策略:用户在银行网站A上访问,cookie记录了A银行存款金额、存款频率、存款频率等信息;当用户离开A网站,访问游戏网站B时,此时网站B可以读取cookie。那么用户的隐私就被泄露了!
更严重的是,cookie往往保存用户登录状态,如果用户离开A网站(但是没有退出登录),那么B网站其实是可以冒充用户进入A网站
4.非同源带来的结果:
cookie,localStorage和indexdDB无法读取
DOM无法获得
Ajax请求无效(请求发送后,浏览器不会进行响应)
第二部分:跨域解决方法
1.设置document.domain来跨子域:(适用于cookie、iframe)
比如和;
如果设置了document.domain='test.com';那么两者之间可以共享cookie(即一级域名相同,二级域名不同,可以设置document.domain来共享cookie)
同时,服务器可以在设置cookie的时候,指定一级域名,也能达到共享cookie的效果。如:Set-Cookie:key=value;domain=.test.com;path=http://www.likecs.com/
iframe:也可以通过上述document.cookie设置,从而共享cookie、iframe拿到父窗口的DOM、父窗口拿到iframe的DOM。
如:父窗口是,iframe是;当设置了document.domain="test.com"时,就能进行跨域了。
2.同源域名下架设代理服务器:JavaScript将请求发送到代理服务器,代理服务器再将结果返回。
如:'/proxy?url=http://www.test.com'
不过这种显然需要配置额外服务器,开销变大。
3.使用window.name来跨域:
window.name:在不同的页面(甚至不同的域名)加载后依然存在(如果值没被修改,则不会发生变化),并且name值可达2MB(对于一般的运用完全够用)
4.片段识别符(fragment identifier):URL中#后面的部分。比如#apple的#apple就是片段识别符。
改变片段识别符,页面不会重新刷新
父窗口将信息,写入子窗口片段识别符;子窗口通过监听hashchange事件得到通知
5.window.postMessage:HTML5为了解决跨域问题,引进的全新API:跨文档通信API(cross-document messaging)
父窗口:,子窗口:;显然两者不同源,但是通过postMessage两者可以实现跨域通信
1 var a=window.open('http://b.com'); 2 //父窗口向子窗口发送信息hello 1 3 a.postMessage('hello 1','http://b.com'); 4 //子窗口向父窗口发送信息hello 2 5 window.opener.postMessage('hello 2','http://a.com'); 6 7 //父窗口和子窗口都能通过message事件,监听对方信息 8 window.addEventListener('message',function(e){ 9 console.log(e.data); 10 })