综合 —— CORS 方式跨域访问

8 篇文章 0 订阅
5 篇文章 0 订阅

一、基础概念

同源策略:

为安全考虑,浏览器会拒绝指向非同源网站的请求。同源指协议、域名、端口相同都相同。举例:

http://www.a.com,协议为http,域名www.a.com,端口默认80,则下面的同源与非同源举例:

http://www.a.com/...:同源;

https://www.a.com/...:不同源(协议不同);

http://service.a.com/...:不同源(域名不同);

http://www.b.com/...:不同源(域名不同);

http://www.a.com:8080/...:不同源(端口不同)。


跨域请求:

非同源的请求,需要跨域才能成功。跨域比较常用的有两种方法:CORS、JSONP,后者是一种非官方方法。



二、通过 Access-Control-Allow-Origin 实现跨域

实验思路:

1、环境配置:tomcat,jdk1.8;

2、实践目的:(1)、学会CORS 跨域访问的基础使用;(2)、探索能否多次跨域(即应用three请求应用one的资源,能否间接通过跨域请求应用two,而应用two再跨域请求应用one实现)

3、项目概况:三个web项目:WebAppOne(访问路径:http://appone.com:8080)、WebAppTwo(访问路径:http://apptwo.com:8080)、WebAppThree(访问路径:http://appthree.com:8080)


实践步骤:

1、项目WebAppOne:

ServletOfAppOne.java 关键代码:

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		
	response.setHeader("Access-Control-Allow-Origin", "*");
	RequestDispatcher rd = request.getRequestDispatcher("indexOfAppOne.html");
	rd.forward(request, response);
}


indexOfAppOne.html:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>应用One</title>
</head>
<body>
	应用One 的首页
</body>
</html>

2、项目WebAppTwo

ServletOfAppTwo.java 关键代码:

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		
	//用于AppThree通过跨域请求此servlet 再次跨域请求AppOne 的服务
       System.out.println("访问应用Two 成功");
        response.setHeader("Access-Control-Allow-Origin", "*");
	RequestDispatcher dispatcher = request.getRequestDispatcher("http://appone.com:8080/ServletOfAppOne");
	dispatcher.forward(request,response);
}

indexOfAppTwo.html:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>应用Two</title>
</head>
<body>
	<fieldset>
		<legend>请求区</legend>
		<button οnclick="requestAppOne()">跨域请求应用One</button>
	</fieldset>
	<fieldset>
		<legend>请求结果</legend>
		<div id="data"></div>
	</fieldset>
	
	<script type="text/javascript">
	
		function ajax(url){  
	        var xhr;  
	        if(window.XMLHttpRequest){  
	            xhr=new XMLHttpRequest();  
	        }  
	        else{  
	            xhr=new ActiveXObject("Microsoft.XMLHTTP");  
	        }  
	        xhr.open("GET",url,true); 
	        xhr.onreadystatechange=function(){  
	            if(xhr.readyState==4&&xhr.status==200){  
	                alert("请求成功");  
	                var msg=xhr.responseText;  
	                document.getElementById("data").innerHTML=msg;  
	            }  
	        }  
	        xhr.send();  
	    }  
		function requestAppOne(){
			ajax("http://appone.com:8080/WebAppOne/ServletOfAppOne");
		}
	</script>
</body>
</html>

3、项目WebAppThree

indexOfAppThree.html:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>应用Three</title>
</head>
<body>
	<fieldset>
		<legend>请求区</legend>
		<button οnclick="requestAppOne()">跨域请求应用One</button>
		<button οnclick="requestAppOnePassByAppTwo()">通过跨域请求应用Two间接跨域请求应用One</button>
	</fieldset>
	<fieldset>
		<legend>请求结果</legend>
		<div id="data"></div>
	</fieldset>
	
	<script type="text/javascript">
	
		function ajax(url){  
	        var xhr;  
	        if(window.XMLHttpRequest){  
	            xhr=new XMLHttpRequest();  
	        }  
	        else{  
	            xhr=new ActiveXObject("Microsoft.XMLHTTP");  
	        }  
	        xhr.open("GET",url,true); 
	        xhr.onreadystatechange=function(){  
	            if(xhr.readyState==4&&xhr.status==200){  
	                alert("请求成功");  
	                var msg=xhr.responseText;  
	                document.getElementById("data").innerHTML=msg;  
	            }  
	        }  
	        xhr.send();  
	    }  
		function requestAppOne(){
			ajax("http://appone.com:8080/WebAppOne/ServletOfAppOne");
		}
		function requestAppOnePassByAppTwo(){
			ajax("http://apptwo.com:8080/WebAppOne/ServletOfAppTwo")
		}
	</script>
</body>
</html>

4、修改hosts 与tomcat 的service.xml 文件,配置项目域名

(1)、修改C:\Windows\System32\drivers\etc\hosts 文件,增加三条:

127.0.0.1 appone.com

127.0.0.1 apptwo.com

127.0.0.1 appthree.com

(2)、修改tomcat 的service.xml 文件,在<Host> 元素体内增加三条:

<Alias>appone.com</Alias>
<Alias>apptwo.com</Alias>
<Alias>appthree.com</Alias>

这样,便为本地tomcat 中项目配置了域名。


5、测试

(1)、浏览器地址栏输入:http://appone.com:8080/WebAppOne/ServletOfAppOne

结果:


(2)、http://apptwo.com:8080/WebAppTwo

结果:


(3)、http://appthree.com:8080/WebAppThree

结果:间接访问AppOne 时,服务器端servlet 中打印了语句,但提示404错误



结论:不能直接跨域访问,不能跨域后再跨域访问第三者。


6、修改WebAppOne 中servlet 允许跨域请求的源

将:

response.setHeader("Access-Control-Allow-Origin", "*");

替换为:

response.setHeader("Access-Control-Allow-Origin", "apptwo.com");

则,WebAppTwo 与WebAppThree都不能访问 WebAppOne 会提示错误:



事实上,经过若干次实践发现,判断能否跨域的工作过程如下:

1、只要服务器端设置了Access-Control-Allow-Origin 头,则所有对该服务的直接请求返回状态都是200,但不一定真正返回数据;

2、Access-Control-Allow-Origin 的值只能为* 或完整的 http://+域名+端口 的形式,如为 http://apptwo.com:8080 时,WebAppTwo 访问时才能真正拿到数据。


可使用数组等 与request 的referer 头等信息实现特定几个网站可访问此应用。


注意:

这种方式js 中ajax 请求时根本不需设置特殊请求头,实际上有的网友说的Origin 等请求头根本不存在,只需写完整路径就行。





  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值