[TOC]javascript
同源策略是对JavaScript
代码可以操做哪些WEB
内容的一条完整的安全限制,也是由Netscape
提出的一个著名的安全策略。所谓同源简单来讲就是“三个相同”,
**
一、域名相同
二、协议相同
三、端口相同
**html
当咱们使用多个<iframe>
元素或者打开其余浏览器窗口的时候,这一策略就会发挥它的做用,在这种状况下,同源策略负责管理窗口或者窗体中的JavaScript
代码以及和其余窗口的交互,具体来讲,脚本只能读取所属文档的来源相同的窗口和文档属性(固然咱们也能够经过JS实现多个窗口和窗体,在本章咱们不作解释)固然同源策略也属于一些理论性的知识点,存在于咱们平常的使用中,了解这些可以帮助咱们更好的理解前端的安全及知识。前端
文档的来源包含协议、主机,以及载入文档的URL
端口。java
一、从不一样的web
服务器载入的文档具备不一样的来源。
二、经过同一主机的不一样端口载入的文档具备不一样的来源。
三、使用http
协议和https
协议载入的文档具备不一样的来源。web
即便他们来自同一个服务器。
脚本自己的来源与同源策略并不相关,相关的是脚本所潜入的文档的来源,同时同源策略还会应用于XMLHttpRequest
生成的HTTP请求,这个对象容许客户端javascript
生成任意的HTTP
请求到脚本所属文档的服务器,可是不容许脚本和其余WEB服务器之间的通讯,这就是咱们常说的跨域请求,其实所谓的跨域就是受到了同源策略的约束,(固然咱们能够经过其余的方式来解决跨域之间的请求的问题)。跨域
同源政策的目的,是为了保证用户信息的安全,防止恶意的网站窃取数据。
设想这样一种状况:A网站是一家银行,用户登陆之后,又去浏览其余网站。若是其余网站能够读取A网站的 Cookie,会发生什么?
很显然,若是 Cookie 包含隐私(好比存款总额),这些信息就会泄漏。更可怕的是,Cookie 每每用来保存用户的登陆状态,若是用户没有退出登陆,其余网站就能够冒充用户,随心所欲。由于浏览器同时还规定,提交表单不受同源政策的限制。
因而可知,"同源政策"是必需的,不然 Cookie 能够共享,互联网就毫无安全可言了。
—— 摘自《浏览器同源政策及其规避方法》数组
在某些状况下,同源策略就显得比较严格了,好比在同一个域名下的其它子域名,例如两个子域名:home.xiang.com
和子域名order.xiang.com
其中的一个子域名下须要合法的读取另外一个子域名地下的文档的属性,为了支持这种多域名站点,这时候咱们可使用document.dimin
属性来控制源,在默认状况下document.domain
的值是载入文档的服务器的主机名,当咱们在设置这一属性的时候,咱们使用的字符串必须具备有效的域前缀或它自己。浏览器
所以若是一个dimin初始值是home.xiang.com
的字符串咱们能够设置为xiang.com
。另外document.domain
的值中必须又一个点号,不能把它设置为com
或者其它顶级域名。安全
这时,若是两个窗体或者窗口包含的脚本吧document.domain
设置成了相同的值,那么两个窗口就再也不受同源策略的约束了。能够相互读取属性了。服务器
受到同源策略的影响,同时咱们也能够经过一些方法来达到跨域资源的共享,参见http://www.w3.org/TR/cors/ 这个标准和草案是用新的Origin:
请求头和新的Access-Control-Allow-Origin
相应来扩展HTTP,它容许服务器用头信息显示的列出源,或使用通配符来匹配全部的源并容许由任何地址请求的文件,不少浏览器都使用这种新的头信息来容许跨域的HTTP请求,这样在咱们的XMLHttpRequest
就不会被同源策略限制。
跨文档消息,容许来自一个文档的脚本能够传递文本消息到另外一个文档里的脚本,而无论脚本的来源是否相同,当咱们调用window对象上的postMessage方法时就能够异步的将信息传递到指定的窗口文档,此时被接受的窗口中能够经过onmessage()
的方法来接收到传递过来的信息,可是不能调用其余文档的方法或者读取属性。也就是说这只是一种通讯技术,并不是是去控制另外一个文档的内容。
postMessage()
方法接受两个参数,第一个参数是要传递的信息,HTML5标准中提到,该参数能够是任意基本类型的只或者是能够复制的对象,可是有些浏览器只支持字符串的传递,全部有时候传递的对象或者数组的时候须要进行转换。第二个参数是一个字符串,是指定窗口的源,也就是指定窗口的document.domain
属性的值,这其中包括了协议、主机名、以及URL端口部分,(除了这些信息以外的信息都会被忽略),若是须要传递给任何窗口,此时这个只能够设置为*
,若是要指定和当前窗口同源的话也可使用/
便可。
在目标窗口就会触发onmessage()
事件,该事件接收到的是一个对象,包含一下属性:
data
做为第一个参数传递给
postMessage()
方法的消息副本内容。
source
消息源自的window对象。
origin
一个字符串,指定消息来源(URL)。
本文大部份内容摘自《JavaScript权威指南》一书,详细解说请参考书中内容。