为什么会有options预检请求?能否移除?
点击上方“Java基基”,选择“设为星标”做积极的人,而不是积极废人!每天14:00更新文章,每天掉亿点点头发...源码精品专栏原创 | Java 2021超神之路,很肝~中文详细注释的开源项目RPC 框架 Dubbo 源码解析网络应用框架 Netty 源码解析消息中间件 RocketMQ 源码解析数据库中间件 Sharding-JDBC 和 MyCAT 源码解析作业调度中间件 Elast...
点击上方“Java基基”,选择“设为星标”
做积极的人,而不是积极废人!
每天 14:00 更新文章,每天掉亿点点头发...
源码精品专栏
从前端的角度看options
options
请求是浏览器的一个机制,不是前端开发人员说不想发options
请求就不发的。当你这个post
请求跨域的时候,那options
请求就出现了(「当然还有put
、delete
请求也会发送预检请求,这些比较少见,在这里我就只谈post
」 )。
options
请求就去问问浏览器,我想跨域ok
不ok
?如果后端设置了允许该域名跨域,那么接着post
请求就正常发送。否则你就会在控制台看到该请求跨域的错误,类似于下面这种
就这么简单,一句话概括:「当跨域的时候,post
请求之前浏览器就会提前发送options
请求,就是询问服务器我能否顺利发送跨域post
请求,如果不能,浏览器Console
就看到跨域错误提示,如果能,post
请求就顺利发送。」
后端配置跨域后,options
请求发到服务器,服务器就会返回,但是没有response data
,你可以当作是浏览器和服务器的悄悄的对话,不是前端开发人员手动控制的,因为options
也不会命中后端某个接口。
本地调试一下,前端发送POST
请求,后端在POST
方法里面打断点调试时,也不会阻碍OPTIONS
请求的返回。
「那么是不是post
请求之前一定会有options
请求呢?不一定,那得看后端怎么配置」
基于 Spring Boot + MyBatis Plus + Vue & Element 实现的后台管理系统 + 用户小程序,支持 RBAC 动态权限、多租户、数据权限、工作流、三方登录、支付、短信、商城等功能
项目地址:https://github.com/YunaiV/ruoyi-vue-pro
视频教程:https://doc.iocoder.cn/video/
从后端的角度看options
从后端的角度看options——post请求之前一定会有options请求?胡说八道!
后端java
配置跨域代码一般如下,供参考
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
@Configuration
public class CorsConfig {
public CorsConfig() {
}
@Bean
public CorsFilter corsFilter() {
// 1. 添加cors配置信息
CorsConfiguration config = new CorsConfiguration();
// Response Headers里面的Access-Control-Allow-Origin: http://localhost:8080
config.addAllowedOrigin("http://localhost:8080");
// 其实不建议使用*,允许所有跨域
config.addAllowedOrigin("*");
// 设置是否发送cookie信息,在前端也可以设置axios.defaults.withCredentials = true;表示发送Cookie,
// 跨域请求要想带上cookie,必须要请求属性withCredentials=true,这是浏览器的同源策略导致的问题:不允许JS访问跨域的Cookie
/**
* withCredentials前后端都要设置,后端是setAllowCredentials来设置
* 如果后端设置为false而前端设置为true,前端带cookie就会报错
* 如果后端为true,前端为false,那么后端拿不到前端的cookie,cookie数组为null
* 前后端都设置withCredentials为true,表示允许前端传递cookie到后端。
* 前后端都为false,前端不会传递cookie到服务端,后端也不接受cookie
*/
// Response Headers里面的Access-Control-Allow-Credentials: true
config.setAllowCredentials(true);
// 设置允许请求的方式,比如get、post、put、delete,*表示全部
// Response Headers里面的Access-Control-Allow-Methods属性
config.addAllowedMethod("*");
// 设置允许的header
// Response Headers里面的Access-Control-Allow-Headers属性,这里是Access-Control-Allow-Headers: content-type, headeruserid, headerusertoken
config.addAllowedHeader("*");
// Response Headers里面的Access-Control-Max-Age:3600
// 表示下回同一个接口post请求,在3600s之内不会发送options请求,不管post请求成功还是失败,3600s之内不会再发送options请求
// 如果不设置这个,那么每次post请求之前必定有options请求
config.setMaxAge(3600L);
// 2. 为url添加映射路径
UrlBasedCorsConfigurationSource corsSource = new UrlBasedCorsConfigurationSource();
// /**表示该config适用于所有路由
corsSource.registerCorsConfiguration("/**", config);
// 3. 返回重新定义好的corsSource
return new CorsFilter(corsSource);
}
}
「这就解决了上面的问题,POST
请求之前不一定有OPTIONS
请求,如果设置了config.setMaxAge
,仅第一次发送OPTIONS
请求,不管POST
请求成功还是失败,在设置的时间范围内,同一个接口请求是绝对不会再次发送OPTIONS
请求的。」
后端需要注意的是,我这里设置允许请求的方法是config.addAllowedMethod("*")
,*
表示允许所有HTTP
请求方法。如果未设置,则默认只允许“GET
”和“HEAD
”。你可以设置的HTTPMethod
为GET
, HEAD
, POST
, PUT
, PATCH
, DELETE
, OPTIONS
, TRACE
经过我的测试,**OPTIONS
无需手动设置,因为单纯设置OPTIONS
也无效** 「。如果你设置了允许POST
,代码为config.addAllowedMethod(HttpMethod.POST);
那么其实已经默认允许了OPTIONS
,如果你」只允许了 GET
,尝试发送POST
请求就会报错如下,预检请求也无法成功响应
预检请求返回403
,服务器拒绝了OPTIONS
类型的请求,因为你只允许了GET
,OPTIONS
类型的请求未被服务器允许。POST
请求的状态显示CORS error
有人会疑问了,如果我既设置了GET
,又设置了OPTIONS
,我能否看到不发送POST
而OPTIONS
成功返回的场景?
config.addAllowedMethod(HttpMethod.GET);
config.addAllowedMethod(HttpMethod.OPTIONS);
答案是否定的,单纯设置OPTIONS
没有意义,现象和上面一样,OPTIONS
响应码仍然403
,POST
没有被发送。
正常情况下我们只要允许了POST
,OPTIONS
就自动允许了,PUT
、DELETE
也一样。所以从后端开发人员角度来看,几乎无需考虑OPTIONS
这种请求,日常需求中POST
请求命中接口时根本感知不到OPTIONS
请求的存在,当然你也可以和上面一样设置OPTIONS
请求的有效时间,在时间范围内,同一个接口的POST
请求之前不会有OPTIONS
请求。
欢迎加入我的知识星球,一起探讨架构,交流源码。加入方式,长按下方二维码噢:
已在知识星球更新源码解析如下:
最近更新《芋道 SpringBoot 2.X 入门》系列,已经 101 余篇,覆盖了 MyBatis、Redis、MongoDB、ES、分库分表、读写分离、SpringMVC、Webflux、权限、WebSocket、Dubbo、RabbitMQ、RocketMQ、Kafka、性能测试等等内容。
提供近 3W 行代码的 SpringBoot 示例,以及超 6W 行代码的电商微服务项目。
获取方式:点“在看”,关注公众号并回复 666 领取,更多内容陆续奉上。
文章有帮助的话,在看,转发吧。
谢谢支持哟 (*^__^*)
更多推荐
所有评论(0)