我们都知道JavaScript可以操作web文档的内容,试想,如果不对这一点加以限制,那么JS可以做的事情就太多了,危险性也太高,所以就针对它可以操作哪些文档的内容有了一个限制,这个限制就是同源策略。
同源策略在什么情况下会起作用呢?当web页面使用多个<iframe>元素或者打开其他浏览器窗口的时候,这一策略就会起作用。
同源策略的含义:脚本只能读取和所属文档来源相同的窗口和文档的属性。
这里就涉及到了一个浏览器如何判断两者是否同源已经如何判断脚本来源的问题。
注意一点:脚本本身的来源并不作为判断是否同源的依据,而是将脚本所属文档的来源作为判断依据。
1. 判断脚本来源
例如:文档A中通过script的src引用了一个外部脚本,这个脚本时google提供的,也是从google的主机上加载到文档A中的,那么这个脚本的所属文档是谁呢,答案是文档A。
2. 判断是否同源
理解了脚本来源,接着理解怎么判断是否同源:如果两个文档在协议、主机以及载入文档的URL端口这三点中有一点不同,就认为他们不同源。
同源策略固然在安全性上有了很大提高,但这种做法属于“宁可错杀三千,不可放过一个”。如果一个多域名站点需要在不同的子域之间共享属性,同源策略就会变得很烦人了。以下介绍三种实现“不严格的同源策略”的方法:
1. 使用Document对象的domain属性
默认情况下,属性domain存放的是载入文档的服务器的主机名。这一属性是可写的。
如果两个窗口包含的脚本把domain设置为了相同的值,那么这两个窗口就不再受同源策略的约束,它们就可以相互读取对方的属性。
2. 跨域资源共享(Cross-Origin Resource Sharing)
这种方法用新的“Origin:”请求头和新的响应头“Access-Control-Allow-Origin”来扩展HTTP。
3. 跨文档消息(Cross-Document Messaging)
允许来自一个文档的脚本可以传递文本消息到另一个文档里的脚本,不管来源是否相同。
调用window对象的postMessage()方法,可以异步传递消息事件到窗口的文档里。这种方法仅仅是一种消息传递技术。