当前位置:Gxlcms >
数据库问题 >
Access control allow origin 简单请求和复杂请求
Access control allow origin 简单请求和复杂请求
时间:2021-07-01 10:21:17
帮助过:27人阅读
- <%@ page language="java" contentType="text/html; charset=UTF-8"
- pageEncoding="UTF-8"%>
- <html xmlns="http://www.w3.org/1999/xhtml" dir="ltr">
- <head>
- <meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
- <title>跨域演示</title>
- <script type="text/javascript" src="jquery-1.11.2.js"></script>
- <script type="text/javascript" src="jquery.form.js"></script>
- </head>
-
- <script type="text/javascript">
- $(document).ready(function() {
-
- $.getJSON(‘http://localhost/test_maven/b.jsp‘, function(data) {
- alert("request succeed");
- });
- });
- </script>
- </body>
b.jsp
[html] view plain
copy
- <%@ page language="java" contentType="text/html; charset=UTF-8"
- pageEncoding="UTF-8"%>
- <%
-
- response.setHeader("Access-Control-Allow-Origin", "*");
- response.getWriter().write("hahahhaha");
- %>
如果注释掉response.setHeader("Access-Control-Allow-Origin", "*");,那么就会出现access control allow origin错误;使用通配符*,允许所有跨域访问,所以跨域访问成功。
但是,请注意使用通配符*,会允许来自任意域的跨域请求访问成功,这是比较危险的,所以在生产环境通常会做更精确控制;
简单请求
上述请求是简单请求,只要添加了Access-Control-Allow-Origin:*,就会访问成功,如果是复杂请求,我们需要更进一步的处理,才能成功。这里先解释一下什么是简单请求和复杂请求。
[html] view plain
copy
- Simple requests
-
- A simple cross-site request is one that meets all the following conditions:
-
- The only allowed methods are:
- GET
- HEAD
- POST
- 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:
- Accept
- Accept-Language
- Content-Language
- Content-Type
- The only allowed values for the Content-Type header are:
- application/x-www-form-urlencoded
- multipart/form-data
- 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
- $.ajax({
-
- type: "post",
- url: "http://localhost/test_maven/a_action",
- contentType: "application/json",
- dataType: "json",
- success: function(){
- alert("request succeed");
- }
- });
[html] view plain
copy
- @RequestMapping(value = "/a_action",
- method=RequestMethod.OPTIONS)
- public void aActionOption(HttpServletResponse response ) throws IOException{
-
- System.out.println("option execute.....");
- response.setHeader("Access-Control-Allow-Headers", "accept, content-type");
- response.setHeader("Access-Control-Allow-Method", "POST");
- response.setHeader("Access-Control-Allow-Origin", "http://192.168.8.36");
- }
[html] view plain
copy
- @RequestMapping(value = "/a_action",method=RequestMethod.POST)
- public void aAction(HttpServletResponse response ) throws IOException{
-
- System.out.println("a_action execute.....");
- }
第一次是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