`
somebody_hjh
  • 浏览: 180922 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

javascript同源策略和跨域实验及其跨域解决办法

阅读更多

一、问题提出: 从应用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><!--url根据跨域更改-->
    </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还是不可行的。如果有页面间的通信机制,其实很多跨域的问题就已经得到解决了。

 

     当然,跨域的解决途径不仅仅只有上面提到的这三种方式。或者你可以也可以想想什么标签的什么特性可以用于跨域呢。

  • 大小: 109.8 KB
  • 大小: 16.7 KB
  • 大小: 12 KB
  • 大小: 16.2 KB
  • 大小: 5.8 KB
分享到:
评论

相关推荐

    JavaScript同源策略和跨域访问实例详解

    本文实例讲述了JavaScript同源策略和跨域访问。分享给大家供大家参考,具体如下: 1. 什么是同源策略 理解跨域首先必须要了解同源策略。同源策略是浏览器上为安全性考虑实施的非常重要的安全策略。 何谓同源: URL由...

    深入浅析同源策略和跨域访问

     理解跨域首先必须要了解同源策略。同源策略是浏览器上为安全性考虑实施的非常重要的安全策略。  何谓同源:  URL由协议、域名、端口和路径组成,如果两个URL的协议、域名和端口相同,则表示他们同源。  同源...

    Tomcat+Nginx反向代理部署前后端分离项目解决跨域问题

    最近自己做了一个前后端分离项目,前端采用HBuilderX开发,后端采用IDEA开发,...同源策略会阻止一个域的javascript脚本和另外一个域的内容进行交互。所谓同源就是两个页面或者前后端的两个地址具有相同的协议(protoc

    详解js跨域原理以及2种解决方案

    主要介绍了js跨域原理以及解决方案,跨域问题是由于javascript语言安全限制中的同源策略造成的,想要进一步了解跨域的朋友可以参考本文进行学习

    javascript 跨域问题以及解决办法

    javascript 跨域问题以及解决办法 什么是跨域问题? 跨域这个问题是由于浏览器的同源策略引起的,请求的URL地址,必须与浏览器的URL是相同协议、相同域名、相同端口的,否则是不允许访问的 浏览器URL 要访问的...

    【JavaScript源代码】解决vue $http的get和post请求跨域问题.docx

    解决vue $http的get和post请求跨域问题  vue $http的get和post请求跨域问题 首先在config/index.js中配置proxyTable proxyTable: { '/api':{ // target:'http://jsonplaceholder.typicode.com', target:'...

    详解JavaScript跨域总结与解决办法

    首先什么是跨域,简单地理解就是因为JavaScript同源策略的限制,a.com 域名下的js无法操作b.com或是c.a.com域名下的对象。更详细的说明可以看下表: URL 说明 是否允许通信 http://www.a.com/a.js ...

    WebApi 跨域问题解决方案:CORS

    同源策略:出于安全考虑,浏览器会限制脚本中发起的跨站请求,浏览器要求JavaScript或Cookie只能访问同域下的内容。 正是由于这个原因,我们不同项目之间的调用就会被浏览器阻止。比如我们最常见的场景:WebApi作为...

    「JavaScript」JS四种跨域方式详解

    浏览器都有一个同源策略,其限制之一就是第一种方法中我们说的不能通过ajax的方法去请求不同源中的文档。 它的第二个限制是浏览器中不同域的框架之间是不能进行js的交互操作的。 三、使用window.name来进行跨域 ...

    主题:javascript最全的10种跨域共享的方法.docx

    在客户端编程语言中,如javascript和ActionScript,同源策略是一个很重要的安全理念,它在保证数据的安全性方面有着重要的意义。同 源策略规定跨域之间的脚本是隔离的,一个域的脚本不能访问和操作另外一个域的绝大...

    跨域解决之JSONP和CORS的详细介绍

    跨域:指的是浏览器不能执行其它网站的脚本,它是由浏览器的同源策略造成的,是浏览器的安全限制! 同源策略 同源策略:域名、协议、端口均相同。 浏览器执行JavaScript脚本时,会检查这个脚本属于那个页面,如果...

    跨域请求资源-jsonp和cors区别.pdf

    那什么是跨域呢,简单地理解就是因为JavaScript同源策略的限制,a.com域名下的js无法操作b.com或是c.a.com域名下的对象。 当协议、子域名、主域名、端口号中任意一个不相同时,都算作不同域。不同域之间相互请求资源...

    javascript-cros:跨域的一些问题和方法总结

    javascript-cros 跨域的一些问题和方法总结 一直都说想找个大总结的文章关于跨域的处理奈何度娘上的资料太老旧,自己对于新的知识点又不是十分十分有研究。因此一直让懒癌发作下去。奈何最近做了双失青年,因此有了...

    简单了解django处理跨域请求最佳解决方案

    为此,浏览器的鼻祖:网景(Netscape)公司提出了优秀的解决方案:著名的浏览器同源策略。现在所有支持JavaScript的浏览器都会使用这个策略。 同源:域名、协议、端口均相同的网站即为同源。 流程: 当一个浏览器的...

    详解Javascript几种跨域方式总结

    在客户端编程语言中如javascript,同源策略规定跨域之间的脚本是隔离的,一个域的脚本不能访问和操作另外一个域的绝大部分属性和方法。只有当两个域具有相同的协议,相同的主机,相同的端口时,我们就认定他们是相同...

    Ajax跨域的完美解决方案

    这里对跨域做个简单介绍以及提供几种解决办法。  由于浏览器实现的同源策略的限制,XmlHttpRequest只允许请求当前源(域名、协议、端口)的资源,所以AJAX是不允许跨域的。这里提供自己常用的三种方法: 1、jsonp...

    用iframe设置代理解决ajax跨域请求问题

    简单的来说,出于安全方面的考虑,页面中的JavaScript无法访问其他服务器上的数据,即“同源策略”。而跨域就是通过某些手段来绕过同源策略限制,实现不同服务器之间通信的效果。 方案:在服务器端创建一个静态的...

    WebApi跨域demon

    同源策略:出于安全考虑,浏览器会限制脚本中发起的跨站请求,浏览器要求JavaScript或Cookie只能访问同域下的内容。 正是由于这个原因,我们不同项目之间的调用就会被浏览器阻止。比如我们最常见的场景:WebApi作为...

Global site tag (gtag.js) - Google Analytics