一.什么是同源策略
同源策略是对JavaScript代码能够和哪些Web内容交互的一条完整的安全限制。当一个Web页面使用多个帧或打开多个浏览器窗口时,这一策略就会发生作用。例如,一个来自域A的脚本包含到一个域B的HTML文档中,这个脚本可以完整的访问域B的HTML文档。如果脚本打开一个新窗口并载入一个来自域B的文档,脚本对这个文档的内容具有完全访问的权限。但是,如果脚本打开一个新窗口并载入一个来自非域B的文档,同源策略就会发挥作用,阻止脚本访问。
对于防止脚本窃取私有信息来说,同源策略是必须的。如果没有这一限制,恶意脚本可能会打开一个空窗口,欺骗用户使用这个窗口浏览,这样恶意脚本就能口读取窗口内容并发回自己的服务器。
不过,在某些情况下同源策略又显得太过严格,它给那些使用多个服务器的大网站带来了一些特殊问题。例如,来自“home.example.com”的脚本可能会想要读取“blog.example.com”装载进来的文档属性,为了支持这种类型的大网站,可以使用“Document”对象的“domain”属性。在默认情况下,“domain”属性存放的是装载文档的服务器主机名,可以设置这一属性,不过它的值必须是有效的域名前缀字符串。如果两个窗口或帧把“domain”属性设置成相同的值,那么这两个窗口或帧就不在受到同源策略的约束,它们可以相互的读取对方的属性。
同源策略阻止从一个源加载的文档或脚本获取或设置另一个源加载的文档的属性。这个策略可以追溯到 Netscape Navigator 2.0。
Mozilla 认为两个页面拥有相同的源,如果它们的协议、端口(如果指明了的话)和主机名都相同。下表给出了相对http://store.company.com/dir/page.html同源检测的结果:
URL
结果
原因
http://store.company.com/dir2/other.html |
成功 |
|
http://store.company.com/dir/inner/another.html |
成功 |
|
https://store.company.com/secure.html |
失败 |
协议不同 |
http://store.company.com:81/dir/etc.html |
失败 |
端口不同 |
http://news.company.com/dir/other.html |
失败 |
主机名不同 |
在同源策略中有一个例外,脚本可以设置 document.domain
的值为当前域的一个后缀,比如域store.company.com的后缀可以是company.com。如果这样做的话,短的域将作为后续同源检测的依据。例如,假设在 http://store.company.com/dir/other.html
中的一个脚本执行了下列语句:
document.domain = "company.com";
这条语句执行之后,页面将会成功地通过对 http://company.com/dir/page.html
的同源检测。而同理,company.com
不能设置 document.domain
为 othercompany.com
.
Original Document Information
- Author(s): Jesse Ruderman
同源策略,它是由Netscape提出的一个著名的安全策略,现在所有的可支持javascript的浏览器都会使用这个策略。
为什么需要同源策略,这里举个例子:
假设现在没有同源策略,会发生什么事情呢?大家知道,JavaScript可以做很多东西,比如:读取/修改网页中某个值。恩,你现在打开了浏览器,在一 个tab窗口中打开了银行网站,在另外一个tab窗口中打开了一个恶意网站,而那个恶意网站挂了一个的专门修改银行信息的JavaScript,当你访问 这个恶意网站并且执行它JavaScript时,你的银行页面就会被这个JavaScript修改,后果会非常严重!而同源策略就为了防止这种事情发生, 看下图:
比如说,浏览器的两个tab页中分别打开了http://www.baidu.com/index.html和http://www.google.com/index.html,其中,JavaScript1和JavaScript3是属于百度的脚本,而JavaScript2是属于谷歌的脚本,当浏览器的tab1要运行一个脚本时,便会进行同源检查,只有和www.baidu.com同源的脚本才能被执行,所谓同源,就是指域名、协议、端口相同。所以,tab1只能执行JavaScript1和JavaScript3脚本,而JavaScript2不能执行,从而防止其他网页对本网页的非法篡改。
二.Selenium Server为什么以这种代理服务器的形式存在
上面说了同源策略,那同源策略的Selenium Server有什么关系呢??呵呵,上一篇说过,Selenium Core是一堆JS函数的集合,它是我们操作浏览器的基础。当存在同源策略时,便出现一些问题,看下图:
因为Selenium Core的JS脚本的“源”是localhost,所以浏览器会阻止Selenium Core的JS脚本在测试页面上执行,这就是为什么在本系列第一篇中说,如果只使用Selenium Core进行测试,需要把Selenium Core安装到远程服务器上。
为了解决上面这个问题,Selenium RC中的Selenium Server就以代理服务器的形式出现了,下图说明它是如何借助代理的身份蒙骗浏览器的:>
Selenium Server以代理的形式存在,通过修改WebSite的源信息,从而达到欺骗浏览器的目的,就这样,Selenium RC就轻松绕过了同源策略。在上图中,浏览器会认为WebSite和Selenium Core来自同一个“源”----代理服务器!
一、问题提出: 从应用A跳转到应用B,用户在应用B上操作完毕后,关闭页面,是否可以用程序自动刷新应用A窗口,以让用户观察操作效果。如支付宝充值,跳转到各银行界面进行充值,充值完毕后,支付宝页面相关自动刷新。(当然由于跨域问题,支付宝并没有这么做,而是弹出层让用户回来确认是否充值完毕)
二、问题分析: 应用A采用域名http://trade.alibaba.com ,应用B采用的域名 http://56.alibaba.com。属于相同主域下的不同子域。牵涉出跨域是否能操作其他文档
三、问题延伸: 了解跨域,我们先了解一下javascript的同源策略,同源策略阻止从一个源加载的文档或脚本获取或设置另一个源加载的文档的属性。如果它们的协议、端口(如果指明了的话)和主机名都相同。则他们属于同源。深入了解同源策略对我们解决问题有很大帮助。
四、实验目的:
1、证明同源策略在各大浏览器下的表现是否统一
2、不同加载方式对同源策略的是否有不同的影响(包括父窗口打开子窗口、父窗口iframe子窗口、ajax调用其他域下的文档加载)
3、探寻解决跨域问题的办法
五、实验准备:
1、根据实验的目的,我们把我们需要做的实验用列表的方式展现出来,方便得出结论。结论填入下表
1 |
类型 |
页面A |
页面B |
页面关系和浏览器表现 (N为出错,Y为正常) |
open |
iframe |
ajax |
ie |
ff |
g |
ie |
ff |
g |
ie |
ff |
g |
2 |
协议、端口、域均相同 |
http://www.alibaba.com/
domain1/a.htm
|
http://www.alibaba.com/
domain2/b.htm
|
Y |
Y |
Y |
Y |
Y |
Y |
Y |
Y |
Y |
3 |
协议、端口、域均相同 |
http://www.alibaba.com:8080/
domain1/a.htm
|
http://www.alibaba.com:8080/
domain2/b.htm
|
Y |
Y |
Y |
Y |
Y |
Y |
Y |
Y |
Y |
4 |
协议不同 |
http://www.alibaba.com/
domain1/a.htm
|
https://www.alibaba.com/
domain2/b.htm
|
|
|
|
|
|
|
|
|
|
5 |
端口不同 |
http://www.alibaba.com/
domain1/a.htm
|
http://www.alibaba.com:8080/
domain2/b.htm
|
N |
N |
N |
N |
N |
N |
N |
N |
N |
6 |
域不同 |
http://www.alibaba.com/
domain1/a.htm
|
http://www.alisoft.com/
domain2/b.htm
|
N |
N |
N |
N |
N |
N |
N |
N |
N |
7 |
子域(主机名)不同 |
http://56.alibaba.com/
domain1/a.htm
|
http://trade.alibaba.com/
domain2/b.htm
|
N |
N |
N |
N |
N |
N |
N |
N |
N |
8 |
子域(主机名)不同,子域为空 |
http://alibaba.com/
domain1/a.htm
|
http://56.alibaba.com/
domain2/b.htm
|
N |
N |
N |
N |
N |
N |
N |
N |
N |
9 |
子域不同设置
document.domain
="alibaba.com"
属性后
|
http://56.alibaba.com/
domain1/a.htm
|
http://trade.alibaba.com/
domain1/a.htm
|
Y |
Y |
Y |
Y |
Y |
Y |
N |
N |
N |
10 |
域不同,IP相同 |
http://56.alibaba.com/
domain1/a.htm
|
http://127.0.0.1/
domain2/b.htm
|
N |
N |
N |
N |
N |
N |
N |
N |
N |
11 |
本地打开 |
file:///D:/test/domain1/
domain1/a.htm
|
http://56.alibaba.com/
domain2/b.htm
|
N |
N |
N |
N |
N |
N |
N |
N/Y |
N |
通过上面的表格,能确定同源策略在各个浏览器的支持程度,并检验各种页面引入方式对同源策略的影响。
2、其中A页面和B页面关系三种情况如下图:
图2-1 window.open打开子窗口
其中A页面源码如下:
- <html>
- <head>
- <title>Page A</title>
- <script>
- alert("domain is:"+document.domain);
- var openerWindow=function(url){
- window.open(url);
- }
- </script>
- </head>
- <body>
-
- <h1 style="text-align:center;font-size:100px;">A</h1>
- <div style="text-align:center"><input type="text" id="mytext" value="I'm page A"/><br/>
- <button onclick="openerWindow('http://www.alibaba.com/domain2/b.htm')">打开子窗口</button>
- </div>
- </body>
- </html>
其中B页面源码如下:
- <html>
- <head>
- <title>Page B</title>
- <script>
- alert("domain is:"+document.domain);
- var refleshOpener=function(){
- window.opener.location.reload();
- }
- </script>
- </head>
- <body>
-
- <h1 style="text-align:center;font-size:100px;">B</h1>
- <div style="text-align:center"><input type="text" id="mytext" value="I'm page B"/><br/>
- <button onclick="refleshOpener()">刷新父窗口</button>
- </div>
- </body>
- </html>
图2-2 iframe引入子窗口
其中A页面源码如下:
- <html>
- <head>
- <title>Page A</title>
- <script>
- alert("domain is:"+document.domain);
- var getValue=function(){
- alert("子窗口中值为:"+window.frames['little_frame'].document.getElementById('mytext').value);
- }
- </script>
- </head>
- <body>
- <h1 style="text-align:center;font-size:100px;">A</h1>
-
- <div style="text-align:center">
- <iframe id="little_frame" name="little_frame" width="300" height="300" src="http://www.alibaba.com/domain2/b.htm"></iframe><br/>
- <input type="text" id="mytext" value="I'm page A"/><br/>
- <button onclick="getValue()">获取子窗口属性</button>
- </div>
- </body>
- </html>
其中B页面源码如下:
- <html>
- <head>
- <title>Page B</title>
- <script>
- alert("domain is:"+document.domain);
- var getValue=function(){
- alert("父窗口中值为:"+top.document.getElementById('mytext').value);
- }
- </script>
- </head>
- <body>
-
- <h1 style="text-align:center;font-size:100px;">B</h1>
- <div style="text-align:center"><input type="text" id="mytext" value="I'm page B"/><br/>
- <button onclick="getValue()">获取父窗口属性</button>
- </div>
- </body>
- </html>
图2-3 ajax的load方法载入B.htm的内容
其中A页面源码如下:
- <html>
- <head>
- <title>Page A</title>
- <script src="jquery-1.3.2.js"></script>
- <script>
- alert("domain is:"+document.domain);
- var loadB=function(){
- $('#loadContentDiv').load("http://www.alibaba.com/domain2/b_ajax.htm");
- }
- </script>
- </head>
- <body>
- <h1 style="text-align:center;font-size:100px;">A</h1>
- <div style="text-align:center">
- <input type="text" id="mytext" value="I'm page A"/><br/><br/>
- <div id="loadContentDiv">这里载入Page B</div>
- <button onclick="loadB()">Ajax载入Page B</button>
- </div>
- </body>
- </html>
其中B页面源码如下:
- <html>
- <head>
- <title>Page B</title>
- <script>
- </script>
- </head>
- <body>
- <h1 style="text-align:center;font-size:100px;">B</h1>
- </body>
- </html>
3、服务器和页面部署:
页面位置如下:
服务器采用tomcat,在tomcat安装目录下conf\Catalina\localhost\ 新建domain1.xml、domain2.xml
配置分别如下:
- <?xml version="1.0" encoding="UTF-8"?> <Context docBase="D:/experiment/domain1" path="domain1" reloadable="true"></Context>
- <?xml version="1.0" encoding="UTF-8"?> <Context docBase="D:/experiment/domain2"
- path="domain2" reloadable="true"></Context>
4、通过host绑定来模拟跨域请求。
通过修改C:/windows/system32/drivers/etc/hosts文件
如在测试第5组时的绑定为:
127.0.0.1 www.alibaba.com
127.0.0.1 www.alisoft.com
六、实验过程
实验过程有些枯燥,对于协议或端口不同的情况,需要在本地架设两套服务器。
其中需要值得说明的是子域的情况:
在验证http://alibaba.com/domain1/a.htm和http://56.alibaba.com/domain2/b.htm的跨域的跨域过程中,有点令人费解的地方。即,页面a.htm不设置document.domain的值,默认为alibaba.com,在b.htm中设置document.domain='alibaba.com'。按道理应该可以绕过跨域的问题,但是这个时候,发现跨域的问题任然存在。于是在a.html中写入 document.domain=document.domain之后,跨域问题就解决了。是不是空的子域跟主域浏览器还是认为有差别呢。
七、实验结论
通过实验,我们可以得出结论
1、主要浏览器对javascript的同源特性的支持良好,不存在有的浏览器不行的情况。
2、对于不同的加载关系,包括open、iframe、ajax方式,也都表现统一。但是ajax加载的时候,在设置document.domain过程中,由于js在载入进来的时候未执行,所以被load页面的document.domain没有生效,造成该方式不能解决ajax的子域跨域问题。但是能用去其他两种打开关系解决子域的跨域。
八、跨域解决办法探讨
1、子域的跨域问题,上面的实验已经解决了两中情况,但是ajax加载的情况,还是得不到解决
2、我们经常引用其他站点的js,比如YUI的库,可以直接在yahoo网站上引用进来,并可以在本页面得到执行。也就是说<script>标签提供跨域特性,那么我们在页面A写入<script src='http://www.domain2.com/getData.jsp'></script>,那么该段js会跨域加载domain2下getData.jsp输出的内容。但是需要保证该输出为js允许的格式,比如是json串。这也就是jsonp的原理了。主要用于ajax跨域请求。但是对于操作跨域打开的窗口和iframe包含的窗口中的内容时,该方法也是力不从心。
3、我们打开一个页面或者嵌入iframe,再或者写入一个连接,经常会用到锚点这个概念。比如<a href='http://www.alibaba.com/b.htm#section1'>第一章节</a>这个#号后面跟的便是锚点的位置,用于页面级的定位。在js里面可以通过hash读取改值。ok,在跨域打开页面或者iframe页面的时候,我们也可以通过该方式写入这个hash值,完成跨域页面间的通信。但是只能父窗口跟子窗口传值,如果子窗口还需要传给父窗口值,那么还需要在子窗口中嵌入iframe,该iframe跟最上面的父窗口同域。这样就可以完成跨域页面的双向通信了。但是相互操作页面dom还是不可行的。如果有页面间的通信机制,其实很多跨域的问题就已经得到解决了。
当然,跨域的解决途径不仅仅只有上面提到的这三种方式。或者你可以也可以想想什么标签的什么特性可以用于跨域呢。
- 大小: 68.9 KB
- 大小: 60.2 KB
- 大小: 75 KB
分享到:
相关推荐
JavaScript跨域和Ajax跨域是Web开发中常见的问题,尤其在进行前后端分离或API调用时,由于浏览器的同源策略限制,不同域名、协议或端口的资源请求会被阻止,这就是所谓的“跨域”。本文将深入探讨JavaScript和Ajax...
总之,jcrossdomain插件提供了一种方便的方式来解决JavaScript的双向跨域问题,通过IFrame和window.postMessage API实现通信,让不同源的Web应用能够安全、高效地共享数据。对于需要在多个域之间进行数据交互的项目...
### JavaScript跨域总结与解决办法 #### 跨域的基本概念 跨域问题源自于浏览器的安全策略之一——**同源策略**。同源策略是浏览器为了防止恶意网站通过脚本访问其他网站的数据而采取的一种安全措施。它规定了一个...
JavaScript跨域是Web开发中一个常见的挑战,由于浏览器的同源策略限制,JavaScript无法直接访问不同源(协议、域名或端口不一致)的资源。本文将深入探讨JS跨域的解决方案,帮助开发者理解并解决这个问题。 首先,...
2. **同源策略**:同源策略是浏览器为了安全而实施的一种策略,规定了只有同源(协议+域名+端口完全相同)的网页才能互相访问对方的DOM元素和JavaScript对象,不同源的页面则受到限制。 3. **iframe跨域问题**:当...
然而,在实际开发过程中,由于浏览器的同源策略限制,当我们在不同域名下尝试访问ArcGIS服务时,会遇到跨域问题。本文档将详细介绍如何在.NET或Java环境下解决这一问题。 跨域问题源于浏览器的安全策略,旨在防止...
跨域是指一个源(Origin,包括协议、域名和端口)试图访问另一个源的资源时受到浏览器同源策略的限制。这种策略是为了保护用户数据安全,防止恶意网站窃取或篡改信息。 **为什么会发生跨域问题?** 跨域是由浏览器...
在Web开发中,由于同源策略的限制,JavaScript通常无法直接访问不同域名下的资源,这就是所谓的跨域问题。然而,为了实现诸如AJAX异步数据交互等需求,开发者需要找到解决这一问题的方法。jQuery作为流行的...
在Web开发中,JavaScript(JS)的同源策略限制了不同源之间进行交互,包括从一个页面中的脚本访问另一个不同源的IFrame内容。"解决JS跨域访问IFrame的解决方案"这一主题关注的就是如何克服这个限制,使得在JSP页面中...
总结来说,JavaScript跨域访问有多种解决方案,开发者应根据具体需求和环境选择合适的方法。JSONP适合简单的GET请求,CORS更通用且安全,代理服务器适用于服务器无跨域控制能力的情况,WebSocket则适用于需要实时...
最近自己做了一个前后端分离项目,前端采用HBuilderX开发,后端采用IDEA开发,...同源策略会阻止一个域的javascript脚本和另外一个域的内容进行交互。所谓同源就是两个页面或者前后端的两个地址具有相同的协议(protoc
标题“javascript/jquery 跨域访问”指的是如何利用JavaScript和jQuery库克服浏览器的同源策略限制,实现在不同源之间进行数据交互。以下是对这一主题的详细阐述: 1. **同源策略**:同源策略是浏览器实施的一项...
首先,需要理解浏览器的同源策略,即浏览器禁止跨域数据访问。这是为了保护用户的安全,因为跨域数据访问可能会带来安全风险。然而,我们可以使用一些技巧来实现跨域数据提交。 在本文中,我们将使用HTML的iframe...
然而,由于浏览器的同源策略限制,Ajax请求只能向同源(协议、域名和端口相同)的服务器发送,这在需要跨域获取数据时就构成了障碍。本篇将详细介绍如何解决Ajax跨域访问的问题。 1. **什么是同源策略** 同源策略...
标题和描述所提及的是一个关于如何解决layer弹窗在跨域环境下的问题,主要涉及到iframe、跨域以及layer的使用技巧。下面我们将详细探讨这个问题及其解决方案。 首先,我们了解下**iframe**。iframe(Inline Frame)...
跨域是指一个源(Origin,由协议、域名和端口组成)试图访问另一个源的资源时,如果这两个源不相同,就会被浏览器视为跨域,从而触发同源策略的限制。为了解决跨域问题,JavaScript提供了一些机制,比如JSONP(JSON ...