当前位置:Gxlcms > 数据库问题 > Access control allow origin 简单请求和复杂请求

Access control allow origin 简单请求和复杂请求

时间:2021-07-01 10:21:17 帮助过:27人阅读

   技术分享技术分享
  1. <%@ page language="java" contentType="text/html; charset=UTF-8"  
  2.     pageEncoding="UTF-8"%>  
  3. <html xmlns="http://www.w3.org/1999/xhtml" dir="ltr">  
  4. <head>  
  5. <meta http-equiv="content-type" content="text/html; charset=UTF-8"/>  
  6. <title>跨域演示</title>  
  7. <script type="text/javascript" src="jquery-1.11.2.js"></script>  
  8. <script type="text/javascript" src="jquery.form.js"></script>  
  9. </head>  
  10.   
  11. <script type="text/javascript">  
  12. $(document).ready(function() {  
  13.       
  14.     $.getJSON(‘http://localhost/test_maven/b.jsp‘, function(data) {  
  15.         alert("request succeed");  
  16.     });  
  17. });  
  18. </script>  
  19. </body>  

 

 

b.jsp

[html] view plain copy    技术分享技术分享
  1. <%@ page language="java" contentType="text/html; charset=UTF-8"  
  2.     pageEncoding="UTF-8"%>  
  3. <%  
  4.   
  5. response.setHeader("Access-Control-Allow-Origin", "*");  
  6. response.getWriter().write("hahahhaha");  
  7. %>  

 

如果注释掉response.setHeader("Access-Control-Allow-Origin", "*");,那么就会出现access control allow origin错误;使用通配符*,允许所有跨域访问,所以跨域访问成功

但是,请注意使用通配符*,会允许来自任意域的跨域请求访问成功,这是比较危险的,所以在生产环境通常会做更精确控制;

 

简单请求

上述请求是简单请求,只要添加了Access-Control-Allow-Origin:*,就会访问成功,如果是复杂请求,我们需要更进一步的处理,才能成功。这里先解释一下什么是简单请求和复杂请求。

 

[html] view plain copy    技术分享技术分享
  1. Simple requests  
  2.   
  3. A simple cross-site request is one that meets all the following conditions:  
  4.   
  5. The only allowed methods are:  
  6. GET  
  7. HEAD  
  8. POST  
  9. Apart from the headers set automatically by the user agent (e.g. Connection, User-Agent, etc.), the only headers which are allowed to be manually set are:  
  10. Accept  
  11. Accept-Language  
  12. Content-Language  
  13. Content-Type  
  14. The only allowed values for the Content-Type header are:  
  15. application/x-www-form-urlencoded  
  16. multipart/form-data  
  17. text/plain  

 

 

简单来说,符合上述条件的都是“简单请求”,除了简单请求就是“复杂请求”。

 

 

复杂请求

在正式post之前,浏览器会先发出一个options请求(也叫preflight),同时header带上origin还有Access-Control-Request-*:**之类的头,服务器响应会返回相应的access-control-allow-origin,如果匹配,那么浏览器就会发送正式post,否则就会出现上述错误。这也解答了,跨域访问时,我们明明发送的post请求,失败的话,查看chrome network会发现是options方法的原因。

根据上述过程,后台方法额外需要options方法,以下是测试样例。

这里的content-type不属于(application/x-www-form-urlencoded,multipart/form-data,text/plain)中的任何一种,所以是复杂请求。

 

 

[html] view plain copy    技术分享技术分享
  1. $.ajax({  
  2.          
  3.           type: "post",  
  4.           url: "http://localhost/test_maven/a_action",  
  5.           contentType: "application/json",  
  6.           dataType:  "json",  
  7.           success: function(){  
  8.             alert("request succeed");  
  9.         }  
  10.       });  



 

 

[html] view plain copy    技术分享技术分享
  1. @RequestMapping(value = "/a_action",  
  2.         method=RequestMethod.OPTIONS)  
  3. public void aActionOption(HttpServletResponse response ) throws IOException{  
  4.       
  5.     System.out.println("option execute.....");  
  6.     response.setHeader("Access-Control-Allow-Headers", "accept, content-type");  
  7.     response.setHeader("Access-Control-Allow-Method", "POST");  
  8.     response.setHeader("Access-Control-Allow-Origin", "http://192.168.8.36");  
  9. }  

 

[html] view plain copy    技术分享技术分享
  1. @RequestMapping(value = "/a_action",method=RequestMethod.POST)  
  2.     public void aAction(HttpServletResponse response ) throws IOException{  
  3.           
  4.         System.out.println("a_action execute.....");  
  5.     }  


第一次是options请求,http options请求跟get、post、head等一样,都属于http的请求方法,options方法,用来获取服务器端某url支持的方法,response header中allow标志支持的方法

 

技术分享

 

第二次才是真正的请求

 

技术分享

 

这个方案是利用了w3c的最新规范,所以该方案依赖浏览器的实现。

 

总结:

出现Access control allow origin错误,说明是跨域请求失败!浏览器发送请求成功,同时浏览器也接收到响应了,但是限制了XmlHttpRquest接收请求,不会让xmlhttprequest接受到响应,并且在js控制台报错。这也就是我们在网络控制台(Network)能看见http 状态码是200,但是在js控制台(Console)出现js错误的原因。

原博客地址:http://blog.csdn.net/wangjun5159/article/details/49096445

相关问题博客:http://www.tangshuang.net/2271.html (解释了什么时候是简单请求什么时候是复杂请求。)

    在ajax中出现options请求,也是一种提前探测的情况,ajax跨域请求时,如果请求的是json,就属于复杂请求,因此需要提前发出一次options请求,用以检查请求是否是可靠安全的,如果options获得的回应是拒绝性质的,比如404\403\500等http状态,就会停止post、put等请求的发出。

Access control allow origin 简单请求和复杂请求

标签:ajax跨域   isa   too   cloud   tps   attribute   ati   问题   head   

人气教程排行