情况描述:

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

项目使用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

前后端分离java、jwt项目进行CORS跨域、解决非简单请求跨域问题、兼容性问题的更多相关文章

  1. 基于Spring Boot+Spring Security+JWT+Vue前后端分离的开源项目

    一.前言 最近整合Spring Boot+Spring Security+JWT+Vue 完成了一套前后端分离的基础项目,这里把它开源出来分享给有需要的小伙伴们 功能很简单,单点登录,前后端动态权限配 ...

  2. springBoot 搭建web项目(前后端分离,附项目源代码地址)

    springBoot 搭建web项目(前后端分离,附项目源代码地址)   概述 该项目包含springBoot-example-ui 和 springBoot-example,分别为前端与后端,前后端 ...

  3. 在前后端分离的SpringBoot项目中集成Shiro权限框架

    参考[1].在前后端分离的SpringBoot项目中集成Shiro权限框架 参考[2]. Springboot + Vue + shiro 实现前后端分离.权限控制   以及跨域的问题也有涉及

  4. [django]前后端分离之JWT用户认证

    在前后端分离开发时为什么需要用户认证呢?原因是由于HTTP协定是不储存状态的(stateless),这意味着当我们透过帐号密码验证一个使用者时,当下一个request请求时它就把刚刚的资料忘了.于是我 ...

  5. 前后端分离之JWT用户认证(转)

    在前后端分离开发时为什么需要用户认证呢?原因是由于HTTP协定是不储存状态的(stateless),这意味着当我们透过帐号密码验证一个使用者时,当下一个request请求时它就把刚刚的资料忘了.于是我 ...

  6. 前后端分离之JWT用户认证zf

    在前后端分离开发时为什么需要用户认证呢?原因是由于HTTP协定是不储存状态的(stateless),这意味着当我们透过帐号密码验证一个使用者时,当下一个request请求时它就把刚刚的资料忘了.于是我 ...

  7. [转] 前后端分离之JWT用户认证

    [From] http://www.jianshu.com/p/180a870a308a 在前后端分离开发时为什么需要用户认证呢?原因是由于HTTP协定是不储存状态的(stateless),这意味着当 ...

  8. 前后端分离之JWT用户认证

    在前后端分离开发时为什么需要用户认证呢?原因是由于HTTP协定是不储存状态的(stateless),这意味着当我们透过帐号密码验证一个使用者时,当下一个request请求时它就把刚刚的资料忘了.于是我 ...

  9. Cookie、Session、Token那点事儿和前后端分离之JWT用户认证

    (两篇文章转自:https://www.jianshu.com/p/bd1be47a16c1:https://www.jianshu.com/p/180a870a308a) 什么是Cookie? Co ...

随机推荐

  1. eclipse启动tomcat访问localhost:8080报404

    直接双击tomcat\bin目录下面的startup.bat启动 是没问题 的 但是eclipse启动tomcat访问localhost:8080报404 解决方案如下: 双击红色圈里面的tomcat ...

  2. windows下java项目打包、启动批处理 .bat文件

    maven打包,脚本内容: @echo off echo 正在设置临时环境变量 set JAVA_HOME=C:\Program Files\Java\jdk1.6.0_45 set MAVEN_HO ...

  3. ipv6_RIPng配置

    ipv6 unicast-routing——类似IPv4的ip routing ipv6 route rip word——启用IPv6进程 防止环路——split-horizon——水平分割——不再接 ...

  4. 蓝桥杯-机器繁殖 第6届C语言C组决赛第4题

    题目叙述: 标题:机器人繁殖 X星系的机器人可以自动复制自己.它们用1年的时间可以复制出2个自己,然后就失去复制能力.每年X星系都会选出1个新出生的机器人发往太空.也就是说,如果X星系原有机器人5个, ...

  5. ES6与ES5的继承

    ES6 ES6中的类 类与ES5中的构造函数写法类似 区别在于属性要放入constructor中,静态方法和属性实列不会继承 <script> class Person{ height=& ...

  6. 八十六、SAP中ALV的事件查看

    一.事务代码SE37,点击运行 二.再点击执行 三.我们可以看到有17个事件,点击17前面的表格图标 四.来到详细的事件中 五.我们回到SE37,点击显示 六.查看参数,为一个内表 七.我们点击SLI ...

  7. 五十二、SAP中的可编辑表格LVC

    一.之前我们写的表格如下,都是通过WRITE输出,不支持同步编辑等操作,给人感觉非常之LOW 二.在SAP中还存在另外一种可编辑的表格,叫LVC表格,效果如下, 三.此可标记表格是座位SAP内置模块来 ...

  8. Python MongoDB 插入文档

    章节 Python MySQL 入门 Python MySQL 创建数据库 Python MySQL 创建表 Python MySQL 插入表 Python MySQL Select Python M ...

  9. Node.js的启动和调试方式

    通过node命令启动 node server/bin/www webstorm配置启动入口 pm2 全局安装:cnpm i pm2 -g 检查版本:pm2 -v 启动:cd 项目目录 pm2 star ...

  10. PHP操作MYSQL数据库(10.11 第十九天)

    一.连接及断开数据库 1.使用mysqli 扩展(推荐),只针对mysql数据库 面向对象的方式 $con = new mysqli(ip,user,password); if($con->co ...