什么是同源?
当两个页面的协议(HTTP,HTTPS),端口,host都相同,那么这两个页面就是同源的。下面是示例。
假设原页面的URL是 http://store.company.com/dir/page.html ,
下表列出了各种URL与该URL是否同源,以及不同源的原因。
URL | 是否同源 | 原因 |
| 是 | |
| 是 | |
| 否 | 协议不同,这里是https |
| 否 | 端口不同 |
| 否 | host不同 |
通常,浏览器会对来自一个源的 document 和 script 与来自另外一个源的 document 和 script 交互加以限制限制。经常遇到的具体情形是浏览器限制当前页面和所包含的 iframe,以及各个 iframe 之间交互的策略。
为什么要有同源策略的存在?
两个字,安全!设想,abc.com 的主页里包含了 gmail.com 的页面,我们肯定不希望看到,在 abc.com 页面里运行的脚本,可以随意修改gmail 页面里的内容和行为,如果执行的是一些恶意脚本,那会相当危险。
同源策略具体内容?
- 符合同源的页面之间的互相访问,交互,是没有限制的;
- 不同源的页面之间的互相访问会受到限制, 就是说当两个 document 不同源时,iframe.contentWindow, window.parent, window.open, window.opener 仅仅提供对另一个 document 的 window 以及 location 的访问,这时候尝试访问其他属性,浏览器会抛出异常,不论是IE,firefox,Chrome 都会抛出一个异常,在某些比较奇葩的情形下,不会抛出异常,仅仅是发出 warn 返回一个 null.
- Ajax 请求的 url 也必须与当前页面是同源的 (不过这也是过去时了,XmlHttpRequest Level 2 里新增了跨域请求 具体请点 )
如何实现同源呢?
在各个 document 内部去执行 document.domain = … 手动把域设置为一样就可以了,但是这里会有一点注意事项:
- 新设的 domain 只能是原 domain 包含的部分。 比如原来的 domain 是 www.google.com.cn, 那么新设置的 domain 的取值只能是 www.google.com.cn, google.com.cn, com.cn, cn和空字符串这几个值,其他任何值都是非法的。
- 当使用 document.domain = … 设置域时,会把端口号 override 掉,设置后当前 document 的 port 为 “”(developer.mozilla.org上说是 null ,但是实际观察了一下,应该是空字符串 “”).