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

状况描述:前端

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

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

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

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

方式一跨域

@CrossOrigin浏览器

在每一个controller类加上spring-mvc

 

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

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

    <mvc:cors>app

        <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");

 

上面三种方式对通常的简单跨域请求有效,能够知足大部分须要。但遇到非简单跨域请求的状况,就会出现问题,须要作一下调整。

 

2、复杂请求下须要对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 {

//使用了方式3、进行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>

3、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

相关文章
相关标签/搜索