同源概述
什么是同源
协议相同 域名相同 端口相同
同源政策的目的
同源政策的目的,是为了保证用户信息的安全,防止恶意的网站窃取数据。
设想这样一种情况:A网站是一家银行,用户登录以后,又去浏览其他网站。如果其他网站可以读取A网站的 Cookie,会发生什么?
不同源的情况会有哪些限制
随着互联网的发展,"同源政策"越来越严格。目前,如果非同源,共有三种行为受到限制。
(1) Cookie、LocalStorage 和 IndexDB 无法读取。
(2) DOM 无法获得。
(3) AJAX 请求不能发送。
如何规避上面的三种限制?
cookie
Cookie 是服务器写入浏览器的一小段信息,只有同源的网页才能共享。
但是,两个网页一级域名相同,只是二级域名不同,浏览器允许通过设置document.domain共享 Cookie。
举例来说,A网页是http://w1.example.com/a.html,B网页是http://w2.example.com/b.html,那么只要设置相同的document.domain,两个网页就可以共享Cookie。
document.domain = 'example.com';
现在,A网页通过脚本设置一个 Cookie。
document.cookie = "test1=hello";
B网页就可以读到这个 Cookie。
var allCookie = document.cookie;
打开的新窗口和当前窗口不同源
如果两个网页不同源,就无法拿到对方的DOM。典型的例子是iframe窗口和window.open方法打开的窗口,它们与父窗口无法通信。
完全不同源的网站,目前有三种方法,可以解决跨域窗口的通信问题。
1、片段标识符
片段标识符(fragment identifier)指的是,URL的#号后面的部分,比如http://example.com/x.html#fra...的#fragment。如果只是改变片段标识符,页面不会重新刷新。
父窗口的
var src = originURL + '#' + data;
document.getElementById('myIFrame').src = src;
子窗口的
window.onhashchange = checkMessage;
function checkMessage() {
var message = window.location.hash;
// ...
}
2、window.postMessage
可以隐藏一个iframe iframe里边的为子页面
子页面发送信息
var ifr=window.parent;
var targeOrigin='http://localhost:63342/reactWork';
ifr.postMessage("asa1111",targeOrigin);
父页面
在父页面中通过 隐藏一个iframe来实现跨域的数据传输
html
<iframe src="http://localhost:3000/talk" id="test"></iframe>
js
<script type="text/javascript">
window.addEventListener('message',function (event) {
console.log(event)
if(event.origin=='http://localhost:1234'){
console.log(event.data) //会输出event的数据
}
},false)
</script>
Ajax
同源政策规定,AJAX请求只能发给同源的网址,否则就报错。
1、jsonp
JSONP是服务器与客户端跨源通信的常用方法。最大特点就是简单适用,老式浏览器全部支持,服务器改造非常小。
基本的思想
网页通过添加一个<script>元素,前端的浏览器向服务器请求JSON数据,这种做法是不会受到同源政策的限制;服务器在收到请求后,将数据放在一个指定名字的回调函数foo里传回来。
前端的js
//动态的插入js脚本
function addScriptTag(src) {
var script = document.createElement('script');
script.setAttribute("type","text/javascript");
console.log(src)
script.src = src;
document.body.appendChild(script);
}
window.onload = function () {
addScriptTag('http://localhost:3000/talk?callback=foo');
}
//传到服务器端的那个回调函数
function foo(data) {
console.log('Your public IP address is: ' + data.ip);
};
服务器端
直接在index.ejs中写 给这个回调函数传递的就是要发送的数据
foo({
"ip": "8.8.8.8"
});
2、websocket 关于websocket可以查看我的另一篇文章
3、cors 关于cors可以查看我的另一篇文章 https://segmentfault.com/a/11...
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。