【转载】跨域请求出现preflight request失败的问题的解决

2023-05-16

本文转载自:https://developer.aliyun.com/article/753657

简介: # 问题出现 这两天在项目联调过程中突然前端同学报告出现CORS跨域问题无法访问。刚听到很奇怪,因为已经在项目里面设置了CORS规则,理论上不会出现这个问题。 ```java protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,

问题出现

这两天在项目联调过程中突然前端同学报告出现CORS跨域问题无法访问。刚听到很奇怪,因为已经在项目里面设置了CORS规则,理论上不会出现这个问题。

    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
                                    FilterChain filterChain) throws ServletException, IOException {
        String orignalHeader = request.getHeader("Origin");

        if (orignalHeader != null ) {
            Matcher m = CORS_ALLOW_ORIGIN_REGEX.matcher(orignalHeader);
            if (m.matches()) {
                response.addHeader("Access-Control-Allow-Origin", orignalHeader);
                response.addHeader("Access-Control-Allow-Credentials", "true");
                response.addHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE, PUT");
                response.addHeader("Access-Control-Allow-Headers", "x-dataplus-csrf, Content-Type");
            }
        }
    }

拿到前端给的错误提示后发现了一个奇怪的问题,提示Response to preflight request doesn't pass access control check中的preflight request是什么?

image.png

Preflight request介绍

了解得知跨域资源共享标准新增了一组 HTTP 首部字段,允许服务器声明哪些源站通过浏览器有权限访问哪些资源。同时规范要求,对那些可能对服务器数据产生副作用的 HTTP 请求方法(特别是 GET 以外的 HTTP 请求,或者搭配某些 MIME 类型的 POST 请求),浏览器必须首先使用 OPTIONS 方法发起一个预检请求(preflight request),从而获知服务端是否允许该跨域请求。服务器确认允许之后,才发起实际的 HTTP 请求。在预检请求的返回中,服务器端也可以通知客户端,是否需要携带身份凭证(包括 Cookies 和 HTTP 认证相关数据)。

一个Preflight request的流程可以如下图所示

image.png

什么样的请求会产生Preflight request呢?当请求满足下述任一条件时,即应首先发送Preflight request请求:

  • 使用了下面任一 HTTP 方法:

    • PUT
    • DELETE
    • CONNECT
    • OPTIONS
    • TRACE
    • PATCH
  • 人为设置了对 CORS 安全的首部字段集合之外的其他首部字段。该集合为:

    • Accept
    • Accept-Language
    • Content-Language
    • Content-Type (需要注意额外的限制)
    • DPR
    • Downlink
    • Save-Data
    • Viewport-Width
    • Width
  • Content-Type 的值不属于下列之一:

    • application/x-www-form-urlencoded
    • multipart/form-data
    • text/plain
  • 请求中的XMLHttpRequestUpload 对象注册了任意多个事件监听器。
  • 请求中使用了ReadableStream对象。

在我们的例子中正是使用了POST方法传递了一个Content-Type为application/json的数据到后端。而这个OPTION请求返回失败后浏览器并没有继续下发POST请求。

解决方案

在弄清楚问题后,我们了解只要给Preflight request优先通过就可以引导后续请求继续下发。对此,我们改造CORS Filter来解决这个问题。

  • 首先对OPTION请求放入HTTP 200的响应内容。
  • 对于Preflight request询问中的的Access-Control-Request-Headers予以通过
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
                                    FilterChain filterChain) throws ServletException, IOException {
        String orignalHeader = request.getHeader("Origin");

        if (orignalHeader != null ) {
            Matcher m = CORS_ALLOW_ORIGIN_REGEX.matcher(orignalHeader);
            if (m.matches()) {
                response.addHeader("Access-Control-Allow-Origin", orignalHeader);
                response.addHeader("Access-Control-Allow-Credentials", "true");
                response.addHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE, PUT");
                response.addHeader("Access-Control-Allow-Headers", request.getHeader("Access-Control-Request-Headers"));
            }
        }

        if ("OPTIONS".equals(request.getMethod())) {
            response.setStatus(HttpServletResponse.SC_OK);
        } else {
            filterChain.doFilter(request, response);
        }
    }

注意事项

但是天不遂人愿,在上述改造后理论上应该是可以解决Preflight request问题,可以测试发现依然有问题。这时我们注意到错误信息中提到的另外一句Redirect is not allowed for a preflight request.

为什么会有Redirect事情发生呢,原来所有请求在进入我们的CORS Filter之前,会首先通过SSO Filter做登录检测。而这个Preflight request并没有携带登录信息,导致OPTION请求被跳转到了登录页面。同理如果引用了Spring Security组件的的话也会出现首先被登录验证给过滤的问题。

找到问题就比较好办了,调整CORS Filter优先级,让其先于登录验证进行就好了。对此我们调整registrationBean的order从默认的Integer.MAX_VALUE到1就好了。

    @Bean(name = "corsFilter")
    public FilterRegistrationBean corsFilter() {
        FilterRegistrationBean registrationBean = new FilterRegistrationBean();
        registrationBean.setFilter(corsFilterBean());
        registrationBean.setUrlPatterns(Lists.newArrayList("/*"));
        registrationBean.setOrder(1);
        return registrationBean;
    }
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【转载】跨域请求出现preflight request失败的问题的解决 的相关文章

随机推荐

  • C++多态性的总结

    抽空总结下对一直以来对C 43 43 多态性的一点个人理解 1 什么叫早绑定和晚绑定 早绑定指在对象声明的时候就和它的类型建立了关联 晚绑定是指代码在运行时再检查对象是否提供了我们所需要的方法和属性 静态关联 早绑定 和动态关联 晚绑定 2
  • 解决不能正常访问workerman的问题

    问题描述 xff1a 在阿里云ECS上部署了workerman的应用 xff08 ECS是专有网络 xff09 xff0c 在ECS安全组里已经允许workerman需要的全部端口 xff0c 但是外网一直不能正常打开 xff08 注 xf
  • 谈谈技术面试

    只要是招一个技术人员 xff0c 不管是初级的程序员还是高级软件工程师 xff0c 技术上的考核都必不可少 很荣幸作为面试官参与过公司的一些技术面试 xff0c 从中也体会到了一些东西 首先 xff0c 我觉得技术面试是需要讲究技巧的 xf
  • H3C交换机配置详解

    一 用户配置 lt H3C gt system view H3C super password H3C 设置用户分级密码 H3C undo super password 删除用户分级密码 H3C localuser bigheap 1234
  • PCL—综述—三维图像处理

    点云模型与三维信息 三维图像是一种特殊的信息表达形式 xff0c 其特征是表达的空间中三个维度的数据 和二维图像相比 xff0c 三维图像借助第三个维度的信息 xff0c 可以实现天然的物体 背景解耦 除此之外 xff0c 对于视觉测量来说
  • yolo 多摄像头_45元的WIFI摄像头应用之YOLO人体识别联动智能家居

    如果大家对智能家居比较感兴趣的话 xff0c 一定知道阻碍智能家居自动化发展的一个大问题就是 xff0c 房间里有没有人 xff0c 如果有人 xff0c 那人究竟在做些什么 xff0c 系统又该如何调整环境的照明 xff0c 温度甚至安防
  • Up Board介绍及上手体验

    Up Board是Intel联合华硕制作的一块性能强悍的卡片电脑 外观如下 xff1a 性能参数如下 xff1a CPU为Intel 凌动z8350系列处理器 xff0c 最高频率可达1 92Ghz xff0c 内核GPU是400核心显卡
  • 卫语句 减少if else的层数

    概述 卫语句是一种写代码的经验 为了减少if else的层数 为了提高可读性 xff0c 进而利于维护 案例 现在做一个需求 xff0c 判断一个人是否满足招聘要求 xff0c 招聘要求 xff1a 30岁以下的中国男性 体重100kg以下
  • ROS自定义msg、srv, 编译时找不到相关头文件

    在我们拥有多个package的时候 xff0c 我们定义了一个消息或者服务 xff0c 并在代码中使用了这个消息或者服务 如果是单独编译这个包 xff0c 编译 通过 但是如果是多个包一起编译 xff0c 就会出现找不到相关头文件的错误 原
  • zz (2006- 11-30更新:ISWC2006论文集已上传)本 版 相 关 资 源 (入门指南,资料软件,网址列表,会议期刊)!...

    原文连接 http bbs w3china org dispbbs asp boardID 61 2 amp ID 61 25 入门材料 注 xff1a 没有链接的文件 xff0c 请前往论坛 FTP xff08 地址用户名密码请看全站置顶
  • 怎么安装winubuntu双系统_双系统中如何重装ubuntu系统图文教程

    今天Win7之家小编就给大家介绍一种双系统中如何重装ubuntu系统图文教程 xff0c 大家之前也是有问过小编双系统中如何重装ubuntu系统 xff0c 但是小编没有及时回答 xff0c 现在小编就给大家介绍双系统中如何重装ubuntu
  • 远程 sshd提示:Server unexpectedly closed network connection

    远程sshd提示 xff1a Server unexpectedly closed network connection 重启后服务器效果也一样 xff0c 经过一段时间连接后 xff0c 终于连上远程了 之后新建一个远程连接 xff0c
  • ubuntu如何跑arm程序

    1 首先确定一间配置好arm linux 交叉编译器 xff0c 可以使用arm linux gcc 2 看示例代码hello c include lt stdio h gt int add int a int b int c 61 a 4
  • 事件引入和本质

    前言 继上一篇委托后 xff0c 我们继续来探讨事件 xff0c 因为委托和事件有着不可分割的关系 通过本文 xff0c 相信你会对事件有更深刻的认识和理解 xff0c 不信 xff0c 你看 xff01 概念 用event 关键字使您可以
  • onlstm时间复杂度_CNN-LSTM | 一种融合卫星-雨量站降水数据的时空深度融合模型

    1 xff0c 不同模型的降水融合性能 表2 2001 2005年全国796个气象站不同降水校正模型的RMSE RB MAE和CC 如表2所示 xff0c 将4种模型结果与原TRMM数据进行了定量比较 xff0c RMSE和MAE值越小表明
  • app 后端技术

    app 后端技术 一直以来工作的方向是web server xff0c 对app server没有什么了解 虽然没有接触过移动app开发 xff0c 但对app后端技术还是挺有探索欲望的 xff0c app应用和web应用在前端的用户习惯不
  • GSM Hacking:使用BladeRF、树莓派、YatesBTS搭建便携式GSM基站

    每次看到黑客在网上发布的那些GSM技术相关文章我都十分惊讶 然而在没有Software Defined Radios SDRs 之前 xff0c 玩GSM并不便宜 xff0c 除此之外想要好好玩你得下大功夫 拓展阅读 GSM BTS Hac
  • 开发新产品的三个验证阶段(EVT/DVT/PVT)

    1 EVT Engineering Validation Test 是针对工程原型机的验证 xff0c 对象很可能是一大块开发板 xff0c 或是很多块开发板 xff1b 关键是要有足够时间和样品 通常 xff0c 如果是新平台 xff0c
  • 大麦盒子显示服务器超时,大麦盒子卡顿怎么办?这几个方法可以快速解决

    原标题 xff1a 大麦盒子卡顿怎么办 xff1f 这几个方法可以快速解决 根据研究表明 xff0c 目前家庭当中电视的使用时间依然在缓慢上升 xff0c 很多家庭会选购一款电视盒子 xff0c 让看电视的体验得到提升 xff0c 但网上很
  • 【转载】跨域请求出现preflight request失败的问题的解决

    本文转载自 xff1a https developer aliyun com article 753657 简介 xff1a 问题出现 这两天在项目联调过程中突然前端同学报告出现CORS跨域问题无法访问 刚听到很奇怪 xff0c 因为已经在