• 前后端分离java、jwt项目进行CORS跨域、解决非简单请求跨域问题、兼容性问题


    情况描述:

    最近在部署一个前后端分离的项目出现了跨域问题*,

    项目使用jwt进行鉴权,需要前端请求发起携带TOKEN的请求*,请求所带的token无法成功发送给后端,

    使用跨域后出现了兼容性问题:Chrome、Firefox浏览器正常,而IE还是报跨域错误

    一、跨域问题在项目中可以使用CORS解决

    方式一

    @CrossOrigin

    在每个controller类加上

     

    方式二 直接在spring-mvc中加入配置

        <!-- 接口跨域配置 -->

        <mvc:cors>

            <mvc:mapping path="/**"

                         allowed-origins="*"

                         allowed-methods="POST, GET, OPTIONS, DELETE, PUT"

                         allowed-headers="Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With"

                         allow-credentials="true" />

        </mvc:cors>

    方式三 可以在interceptor中向response增加header

            response.setHeader("Access-Control-Allow-Origin", "*");

            response.setHeader("Access-Control-Allow-Credentials", "true");

            response.setHeader("Access-Control-Allow-Methods", "GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS");

            response.setHeader("Access-Control-Max-Age", "86400");

            response.setHeader("Access-Control-Allow-Headers", "Authorization,Overwrite, Destination, Content-Type, Depth, User-Agent, Translate, Range, Content-Range, Timeout, X-File-Size, X-Requested-With, If-Modified-Since, X-File-Name, Cache-Control, Location, Lock-Token, If");

     

    上面三种方式对一般的简单跨域请求有效,可以满足大部分需要。但遇到非简单跨域请求的情况,就会出现问题,需要做一下调整。

     

    二、复杂请求下需要对options预检请求进行处理

     

    前后端分离的项目中,浏览器请求中经常会出现非简单跨域请求,这将会发送请求2次,第一条由浏览器发起请求为options的预检请求,再根据服务器的返回内容由浏览器判断服务器是否允许此次请求,第二条才是method中的get,post或者put等,并且第一条无任何数据返回,第二条才正常返回数据。

     

    所以我们会遇到:我们处理token的拦截器(非简单情况,header的authorization携带了token进行鉴权),在接收到option的时候将这个预检请求当成正常的请求,而options请求时无法在header携带token的,因此后端将会把第一个请求打回,导致第二个请求无法正常发起。

     

    非简单情况(含以下之一):

    1. 请求方式:PUT、DELETE
    2. 自定义头部字段
    3. 发送json格式数据
    4. 正式通信之前,浏览器会先发送OPTION请求,进行预检,这一次的请求称为“预检请求”
    5. 服务器成功响应预检请求后,才会发送真正的请求,并且携带真实数据

     

    解决方式  在后端中对options请求进行直接给通过(只要返回200、204,浏览器即判断服务器允许请求)

    增加一个CorsInterceptor

    public class CorsInterceptor implements HandlerInterceptor {
    
    //使用了方式三、进行CORS配置
    
            response.setHeader("Access-Control-Allow-Origin", "*");
    
            response.setHeader("Access-Control-Allow-Credentials", "true");
    
            response.setHeader("Access-Control-Allow-Methods", "GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS");
    
            response.setHeader("Access-Control-Max-Age", "86400");
    
            response.setHeader("Access-Control-Allow-Headers", "Authorization,Overwrite, Destination, Content-Type, Depth, User-Agent, Translate, Range, Content-Range, Timeout, X-File-Size, X-Requested-With, If-Modified-Since, X-File-Name, Cache-Control, Location, Lock-Token, If");
    
            if(HttpMethod.OPTIONS.toString().equals(httpServletRequest.getMethod())){
    
                response.setStatus(HttpStatus.NO_CONTENT.value());
    
                System.out.println("是options请求、跳过");
    
                return false;
    
            }
    
            return true;
    
        }
    
    }
    

      

    spring-mvc中加载这个CorsInterceptor,置于token处理之前

            <mvc:interceptor>
    
                <mvc:mapping path="/**" />
    
                <bean class="cn.gdyvc.interceptor.CorsInterceptor" />
    
            </mvc:interceptor>

    三、CORS浏览器兼容问题

     

    最后部署完成,但是Chrome、Firefox浏览器正常,而IE还是报跨域错误,遇到了Internet Explorer与Access-Control-Allow-Methods的CORS问题

    刚开始跨域配置根据网上的的设置将Access-Control-Allow-Headers对应设置为“*”,而Ie的是不能够响应*的,需要将header的各列单独列出来

     

    参考链接:

    https://www.jianshu.com/p/5c637bfcc674

    https://stackoverflow.com/questions/51857247/ie-cors-access-control-allow-headers-error-even-though-headers-are-specified

    https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Headers

  • 相关阅读:
    镜像切换Logreader Agent报错:分发数据库中可能存在不一致的状态(续)
    镜像切换Logreader Agent报错:分发数据库中可能存在不一致的状态
    SQL优化案例—— RowNumber分页
    SQL Server 服务器磁盘测试之SQLIO篇(二)
    SQL Server 服务器磁盘测试之SQLIO篇(一)
    SQL Server内存遭遇操作系统进程压榨案例
    git添加ssh公钥报错
    leetcode_1187. Make Array Strictly Increasing 使数组严格递增_[DP]
    leetcode_1293. Shortest Path in a Grid with Obstacles Elimination_[dp动态规划]
    leetcode_1292. Maximum Side Length of a Square with Sum Less than or Equal to Threshold_[二维前缀和]
  • 原文地址:https://www.cnblogs.com/liqiujiong/p/12370207.html
Copyright © 2020-2023  润新知