同源策略指的是三个相同
- 协议相同
- 域名相同
- 端口相同
如https://www.baidu.com/hahah.html这个网址来说 https是使用的协议,www.baidu.com是域名,端口号默认是80(不指定端口默认是80端口);
所以:
- www.baidu.com/hehe.html 同源
- www.baidu.com/heihei/houhou.html 同源
- www.i71.com/haha.html 域名不同,不同源
- www.baidu.com:888/haha.html 端口不同,不同源
为什么需要同源策略
同源策略其实是一种浏览器安全的功能,保护着每个网站数据的安全的同时又维持着js脚本的正常执行;假设现在两个网页,百度和谷歌的,两个网页都会加载各自的js脚本或者添加cookie等等,同源策略就是维持这些数据和脚本的有序访问;百度网页的脚本不能访问谷歌网页的脚本,当然各自的cookie数据也只能各家的js 脚本才能访问;
ps: 如果非同源,那么以下的行为将会受到限制;1,cookie,localStorage 2,ajax
需要跨域取数据怎么办(多个服务器,或者二级域名)
1.利用cookie设置document.domain (解决二级域名不同)
比如www.baidu.com和news.baidu.com这两个不同的域名,要想让两者之间的数据能够互相访问,可以将数据存储在cookie里面并指定
document.domain="baidu.com";
2 命名锚点(www.aaa.com#tag)(解决嵌套窗口)
要利用这个呢,就得说说的网站url,在js中如何存储这些信息来让我们访问呢?——window.location 以我现在编辑文章的界面来说:
这个就是window.location对象,location.hash里面存放的是#tag,也就是锚点名;(当然了,除此之外还有很多其他有用的属性,host,href,origin,pathname(查询路径),search(查询字符串));
所以,现在添加一个锚点,location.hash="lla";
页面url已经改变,当然这时候嵌套的子窗口也能访问到我添加的这个lla名称了,达到了传值得目的,那么问题来了,为什么不用查询字符串?xxx=xxx;这个来传值呢,首先锚点不会刷新页面,如果你改变了location.search(或者host,href啊)都会触发页面的刷新行为,什么,,,你竟然不信??
果断选择留下来;信了就好;
那么子窗口如何获得这个事件的改变;window.haschange
window.hanschange=function(){
var tag=window.location.hash; }
同样的子窗口也可以改变这个tag;parent.location.hash=XXX;
3,正经做法,html5给了解决这个问题的API了
windw.postMessage看名字就很有感觉,post,恩,看来蛮安全的吗;所以有了这个方式,不管两个网页是不是同源,都可以愉快的好好沟通了
MDN上面给的解释是:
The
W
indow.postMessage()
method safely enables cross-origin communication. Normally, scripts on different pages are allowed to access each other if and only if the pages that executed them are at locations with the same protocol (usually bothhttps
), port number (443
being the default forhttps
), and host (moduloDocument.domain
being set by both pages to the same value).window.postMessage()
provides a controlled mechanism to circumvent this restriction in a way which is secure when properly used.
那么如何使用?
发送端:
接受端:
不多逼逼;window.postMessage的MDN详细资料:https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage
ps:postMessage我还没有实战经验,有实战经验放demo,不过讲道理控制台应该也能实现这个demo;有弄再补写
-----------------------------------------------------------------------2017-4-11----------------------------------------------------------------------------------------------
在搜狗页面:
用window.open打开百度界面,在这个打开的页面里面添加message监听:
接下来从搜狗页面向百度发送字符串消息:
查看百度页面输出的数据:
成功!e.origin指向了搜狗页面的网址;
这是字符串数据;然后测试下其他类型;
查看结果:
没问题,安心用吧;