转载请注明出处

原文链接:https://blog.csdn.net/qq_39309348/article/details/103267908

在正式跨域的请求前,浏览器会根据需要,发起一个“PreFlight”(也就是Option请求),用来让服务端返回允许的方法(如get、post),被跨域访问的Origin(来源,或者域),还有是否需要Credentials(认证信息)

发送option请求的原因

如果跨域的请求是Simple Request(简单请求 ),则不会触发“PreFlight”。Mozilla对于简单请求的要求是:

以下三项必须都成立:

1. 只能是Get、Head、Post方法

2. 除了浏览器自己在Http头上加的信息(如Connection、User-Agent),开发者只能加这几个:Accept、Accept-Language、Content-Type、。。。。

3. Content-Type只能取这几个值:

  • application/x-www-form-urlencoded
  • multipart/form-data
  • text/plain

当不满足上面的条件是,就会发送options预请求,一般是因为修改了application/json,所以才导致发送option请求

问题

当发送option时,所有的参数都为null,后端如果做了参数非空校验的话,就会报错,缺少必要的参数*

解决方案

一、过滤器过滤options请求

这种方法也不失为一种好方法,注意if(OPTIONS.equalsIgnoreCase(request.getMethod())) return; 必须放在response....之后,否则options成功了,post发送不了

@WebFilter(filterName = "CorsFilter", urlPatterns = "/*")
public class CorsFilter implements Filter {private static final String OPTIONS = "OPTIONS";@Overridepublic void init(FilterConfig filterConfig) throws ServletException {}@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {HttpServletRequest request = (HttpServletRequest) servletRequest;HttpServletResponse response = (HttpServletResponse) servletResponse;response.addHeader("Access-Control-Allow-Origin", "*");response.setHeader("Access-Control-Allow-Methods", "POST,GET,PUT,DELETE,OPTIONS");response.addHeader("Access-Control-Allow-Headers", "*");//response.addHeader("Access-Control-Max-Age", "3628800"); //可选if(OPTIONS.equalsIgnoreCase(request.getMethod()))return;  // 或者直接输入204、HttpStatus.SC_OK、200,等这些都可以   import org.apache.http.HttpStatus;filterChain.doFilter(servletRequest, response);}@Overridepublic void destroy() {}
}

二、过滤器添加Access-Control-Max-Age缓存

这种方法不可避免第一次会发送options预请求,如果后端做了非空校验,一样是会出现问题。

public class CorsFilter implements Filter {@Overridepublic void init(FilterConfig filterConfig) throws ServletException {}public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {HttpServletResponse response = (HttpServletResponse) servletResponse;response.addHeader("Access-Control-Allow-Origin", "*");response.setHeader("Access-Control-Allow-Methods", "POST,GET,PUT,DELETE,OPTIONS");response.addHeader("Access-Control-Allow-Headers", "*");response.addHeader("Access-Control-Max-Age", "3600"); //3600秒内不会发送预请求filterChain.doFilter(servletRequest, response);}@Overridepublic void destroy() {}
}

三、使用springboot自带的CROS

和使用过滤器response来添加请求头相比,springboot已经帮我们处理好了options请求,而自己写的过滤器得自己去处理

@SpringBootApplication
@Configuration
public class ApplicationA extends WebMvcConfigurerAdapter {public static void main(String[] args) {SpringApplication.run(ApplicationA.class, args);}// 跨域支持@Overridepublic void addCorsMappings(CorsRegistry registry) {registry.addMapping("/**") //所有方法.allowedOrigins("*") //允许的域名.allowCredentials(true) .allwoedHeaders("*") // 允许请求头.allowedMethods("GET", "POST", "DELETE", "PUT","OPTIONS")//允许方法.maxAge(3600); //表明在3600秒内,不需要再发送预检验请求,可以缓存该结果}
}

JAVA解决OPTIONS请求问题:跨域时ajax发送两次请求,其中options预请求参数为null及其解决方案相关推荐

  1. 解决阿里云OSS跨域问题

    解决阿里云OSS跨域问题 现象 本人项目中对阿里云图片请求进行了两次,第一次通过img标签进行,第二次通过异步加载获取.第一次请求到图片,浏览器会进行缓存,随后再进行异步请求,保存跨域失效. 错误信息 ...

  2. http跨域时的options请求

    一.简介 出于安全考虑,并不是所有域名访问后端服务都可以.其实在正式跨域之前,浏览器会根据需要发起一次预检(也就是option请求),用来让服务端返回允许的方法(如get.post),被跨域访问的Or ...

  3. 解决java前后端分离端口跨域问题

    解决java前后端分离端口跨域问题 参考文章: (1)解决java前后端分离端口跨域问题 (2)https://www.cnblogs.com/mollie-x/p/10449686.html 备忘一 ...

  4. 解决 用 Nginx 处理 跨域问题

    教你 如何 快速 用 Nginx 轻松搞定跨域问题 当你遇到跨域问题,不要立刻就选择复制去尝试.请详细看完这篇文章再处理 .我相信它能帮到你. 分析前准备: 前端网站地址:http://localho ...

  5. 用P3P header解决IE下iframe跨域访问时候session丢失的问题

    用P3P header解决IE下iframe跨域访问时候session丢失的问题 整合客户的登录时,或者其他一个网站通过iframe时,特别是一个http页面,访问一个https页面时,常常会sess ...

  6. vb跨域访问ajax,解决AJAX的跨域访问-两种有效示例

    这篇文章主要为大家详细介绍了解决AJAX的跨域访问-两种有效示例,具有一定的参考价值,可以用来参考一下. 感兴趣的小伙伴,下面一起跟随512笔记的小玲来看看吧!新的W3C策略实现了HTTP跨域访问,还 ...

  7. CORS跨域时axios无法获取服务器自定义的header信息 - 番外篇

    已解决CORS跨域时axios无法获取服务器自定义的header信息?! 先看代码: // 登录后的表单提交ajaxRegisterApi: function (form) { var key = l ...

  8. 解决Vue前后端跨域问题的多种方式

    1 前言 本文主要介绍借助解决Vue前后端跨域问题的几种方式 说到ajax请求,就不得不说下xhr(XMLHttpRequest)了,它可以说是鼻祖,但是实际开发中,我们不会直接使用它,而是进行二次封 ...

  9. 解决前端 node 环境跨域与404问题,yog2

    问题背景: 前端通常会有两种架构,一种是无前后端分离的,前端为后端提供渲染模板,这种方式把前后端开发人员绑定到了一起,很不灵活:另一种是前后端分离,也是目前大多数公司在走的路线,通常会使用 node ...

最新文章

  1. 在java的程序里date类型比较大小
  2. CSDN湘苗培优,遇见更好的自己
  3. Linux RCU机制详解[转]
  4. 关于Update语句在不同数据库中的差别
  5. 【十九】require和include的区别
  6. 用JQUERY实现给当前页面导航一个CSS
  7. 西门子宣布美国充电桩扩产计划
  8. 图片上传的ajax代码,一个伪ajax图片上传代码的例子
  9. 游戏筑基开发之二进制文件操作的那点事儿(C语言)
  10. 计算机类专业毕业设计(课程设计)题目大全
  11. 用php设置留言无数据库_PHP留言板无数据库版
  12. 解决Windows聚焦不更新图片问题
  13. python xps_python处理xps文件_从XPS文档中提取文本
  14. 领导的这些职场暗语,你一定要知道!
  15. 计算机英语阅读路线,计算机经典英语短文阅读
  16. 计算机里的声卡的主要作用,声卡是什么?他的主要作用有哪些?
  17. 天龙八部 - 其它 - 手工选择
  18. MySQL——in和exists优化
  19. java8新特性学习笔记之唠唠“匿名内部类与lambda”
  20. 美国各名校恶搞版的自我介绍

热门文章

  1. Nmon服务器资源监控工具
  2. git lfs原理和使用
  3. GSMA移动360会议首次亮相马来西亚
  4. java之简易的文件加密器的实现
  5. 测试sony电视屏的软件,Mirror for Sony TV 3.6.2 for Mac 索尼电视屏幕镜像工具
  6. 神舟战神z7装linux,【神舟超级战神K670E试用】K670E安装系统
  7. android 多闹钟实现代码,Android重复闹钟(每天)的实现
  8. linux程序作为桌面壁纸,在Linux系统下安装壁纸程序Wonderwall,附主要功能介绍
  9. vbox导入以前的虚拟机_vbox安装虚拟机导入或导出
  10. 惠普288ProG6台式机win10改win7系统及bios设置【支持10代cpu】