为什么ajax方法发出的post请求会生成options预请求?
1 问题说明
最近在项目中使用ajax方法发送一个post请求时在后台通过HttpServletRequest的getMethod方法拦截到了http options请求,但是我并没有发送options预请求呀,这是怎么回事呢?
2 问题分析
options预请求会在什么情况下出现:
1、跨域调用,例如:调试时候很多情况都是在跨域的情况下进行调试。
2、自定义请求头部header字段:比如业务需求,传一个字段,方便后端获取,不需要每个接口都传。
3、请求头的content-type参数是"application/x-www-form-urlencoded"、"multipart/form-data"、"text/plain"之外的其它格式,例如:application/json。
以上三种情况出现就会出现options请求了,说白了就是为了服务器安全,例如:同源策略引发这个规则;options通常是浏览器自动发起的,目的就是去服务器检查一下接下来要用到的方法(GET、POST、PUT、DELETE)在服务器上是否支持。
3 相关说明
3.1 什么是预请求?
预请求就是复杂请求(可能对服务器数据产生副作用的http请求方法,如put,delete都会对服务器数据进行修改,所以要先询问服务器)。
跨域请求中,浏览器自发的发起预请求,浏览器会查询到两次请求,第一次的请求参数是options,以检测实际请求是否可以被浏览器接受。
3.2 为什么需要预请求?
w3c规范要求,对复杂请求,浏览器必须先使用options发起一个预检请求,从而获知服务器是否允许该跨域请求,服务器确认以后才能发起实际的HTTP请求,否则停止第二次正式请求。
那为什么我们不常见options请求呢?因为大部分我们使用的是get,post请求,他们属于简单请求,而简单请求不会触发options请求。
3.3 为什么需要设置成contentType:"application/json"?
ajax发送复杂的json数据结构, 处理方式困难, 服务器端难以解析, 所以就有了application/json这种类型(数据格式的声明)服务端好解析并且比较统一,如果你请求中没有设置成json格式的,有的服务端收到后也会改成json格式的,但是如果请求中就改成了json格式就会发生options预请求。
如果设置了contentType:"application/json":
- ajax的data只能是json格式的字符串,发送的json对象必须使用json.stringify进行序列化字符串才能匹配。
- Spring需要使用@RequestBody来注解。
例如:
$.ajax({ url: actionurl, type: "POST", datType: "JSON", contentType: "application/json" data: "{'id': " + nodeId +"}", async: false, success: function () {} });
如果没有设置contentType:"application/json"的话,那么ajax的data可以是对象,例如:
$.ajax({
url: actionurl,
type: "POST",
datType: "JSON",
data: { id: nodeId },
async: false,
success: function () {}
});
3.4 options的作用
OPTIONS请求方法的主要用途有两个:
- 获取服务器支持的HTTP请求方法;也是黑客经常使用的方法。
- 用来检查服务器的性能。例如:AJAX进行跨域请求时的预检,需要向另外一个域名的资源发送一个options请求头,用以判断实际发送的请求是否安全。
参考资料
- 1vue和el-table使用经验-如何刷新表格数据10948
- 2three.js加载3D瓦片和3dtiles数据生成交互式地图的开源项目9497
- 3Microsoft Visual C++ Redistributable是什么,有什么作用?7274
- 4mybatis使用经验——mybatis-spring-boot-starter和mybatis的版本对应关系表(持续更新~)5841
- 5uni-app使用经验—vue页面和html页面如何互相调用接口并传参5480
- 6Intellij IDEA下的版本控制VCS的启用与关闭4894
- 7Spring学习经验—@ResponseBody注解的使用说明4890
- 8Druid异常解决经验—java.sql.SQLException url not set4513
- 9如何用批处理命令(bat脚本)启动和停止windows服务4282
- 10nuxt.js项目中如何添加和使用全局变量4158
- 11解决SpringBoot使用maven下载不了jar包的问题3497
- 12linux中解压tar.gz文件报错“gzip: stdin: invalid compressed data--format violated”3394
- 13nuxtjs asyncData使用经验—如何发起多个axios请求并携带参数3246
- 14在Nuxt.js项目的head中引用外部js文件3088
- 15在NVIDIA控制面板设置参数时提示“拒绝访问 无法应用选定的设置到您的系统”的解决方法之一3066