首先配置允许跨域

@Configuration
public class CorsConfig extends WebMvcConfigurerAdapter {@Overridepublic void addCorsMappings(CorsRegistry registry) {registry.addMapping("/**").allowedOrigins("*").allowCredentials(true).allowedMethods("GET", "POST", "DELETE", "PUT").maxAge(3600);}
}

因项目需对用户校验,因此配置了过滤器,
然后出现问题:

  **1.过滤器拦截后,页面提示没有跨域2.在过滤器配置跨域后,返回responsebody是空的**

代码如下:


import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.ApplicationContext;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.web.context.support.WebApplicationContextUtils;import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;@Slf4j
@Component
@WebFilter(filterName = "sessionFilter", urlPatterns = {"/*"})
public class SessionFilter implements Filter {@Value("${manage.session.timeout}")private long timeout;private final ObjectMapper mapper = new ObjectMapper();//不需要登录就可以访问的路径(比如:注册登录等)String[] includeUrls = new String[]{"/web-manage/su/submitLogin", "/su/submitLogin"};/*** 登录校验** @param servletRequest* @param servletResponse* @param filterChain* @throws IOException* @throws ServletException*/@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,FilterChain filterChain) throws IOException, ServletException {HttpServletRequest request = (HttpServletRequest) servletRequest;HttpServletResponse response = (HttpServletResponse) servletResponse;log.info("Headers:{}", response.getHeader("Access-Control-Request-Headers"));//String origin = request.getHeader("Origin");//if (origin == null) {//    origin = request.getHeader("Referer");//}//response.setHeader("Access-Control-Allow-Origin", origin);//使用通配符responseBody是空的!放开上段代码后项目正常response.setHeader("Access-Control-Allow-Origin", "*");response.setHeader("Access-Control-Allow-Credentials", "true");response.setHeader("Access-Control-Allow-Methods", "*");response.setHeader("Access-Control-Allow-Headers", "Content-Type,Access-Token");response.setHeader("Access-Control-Expose-Headers", "*");String uri = request.getRequestURI();String jsessionId = "";log.info("uri :{}, request.getContentType(): {}", uri, request.getContentType());//是否需要过滤boolean needFilter = isNeedFilter(uri, includeUrls);if (!needFilter) {//不需要过滤直接传给下一个过滤器filterChain.doFilter(servletRequest, servletResponse);} else {Cookie[] cookies = request.getCookies();if (cookies == null || cookies.length == 0) {cookieNoJessionid(response);} else {for (Cookie cookie : cookies) {if (CommonConstant.JSESSIONID.equals(cookie.getName())) {jsessionId = cookie.getValue();break;}}log.info("ContentType:" + request.getContentType());if (request.getMethod().equals("OPTIONS")) {response.setStatus(HttpStatus.OK.value());return;}RequestWrapper requestWrapper = null;if (request instanceof HttpServletRequest) {if ("POST".equals(request.getMethod().toUpperCase())&& request.getContentType() != null&& request.getContentType().contains("application/json")) {requestWrapper = new RequestWrapper(request);}}judgeLogin(jsessionId, response, request, requestWrapper, filterChain);}}}/*** 判断是否已登录** @param jsessionId* @param response* @param request* @param requestWrapper* @param filterChain* @throws IOException* @throws ServletException*/private void judgeLogin(String jsessionId, HttpServletResponse response, HttpServletRequest request,RequestWrapper requestWrapper, FilterChain filterChain) throws IOException, ServletException {// 判断 jsessionId 是否为空if (StringUtils.isBlank(jsessionId)) {cookieNoJessionid(response);} else {// 获取ValueOperations beanServletContext context = request.getServletContext();ApplicationContext ctx = WebApplicationContextUtils.getWebApplicationContext(context);ValueOperations valueOperations = (ValueOperations) ctx.getBean("valueOperations");// 获取用户信息String userBoStr = (String) valueOperations.get(RedisConstant.REDIS_LOGIN + jsessionId);SysUserBo sysUserBo = mapper.readValue(userBoStr, SysUserBo.class);if (sysUserBo != null) {filterChain.doFilter(request == null ? requestWrapper : request, response);} else {// 返回登录超时提醒response.setContentType("application/json");response.setCharacterEncoding("UTF-8");response.setStatus(HttpStatus.UNAUTHORIZED.value());response.getWriter().write(this.mapper.writeValueAsString(ResultUtil.errorResult(ExceptionEnum.ERROR_PARAMETERS.getCode(), "jsessionid 登录超时")));}}}/*** cookie 无jsessionid* @param response* @throws IOException*/private void cookieNoJessionid(HttpServletResponse response) throws IOException {response.setContentType("application/json");response.setCharacterEncoding("UTF-8");response.setStatus(HttpStatus.UNAUTHORIZED.value());response.getWriter().write(this.mapper.writeValueAsString(ResultUtil.errorResult(ExceptionEnum.ERROR_PARAMETERS.getCode(),"jsessionid 为空!")));}/*** @param uri* @Description: 是否需要过滤*/public boolean isNeedFilter(String uri, String[] includeUrls) {for (String includeUrl : includeUrls) {if (includeUrl.equals(uri)) {return false;}}return true;}@Overridepublic void init(FilterConfig filterConfig) throws ServletException {}@Overridepublic void destroy() {}
}

百度一波,给出的解释是:
出自:https://www.cnblogs.com/nopnog/articles/9133115.html
Access-Control-Allow-Origin 的正确玩法
  前端发起的跨域请求需要适当地响应 Access-Control-Allow-Origin 头。但是这个头目前并不支持部分通配符,无法匹配某个域名下的子域。直接使用星号又可能带来各种问题。更坑爹的是它还不支持设置多个值。那么如果一个后端程序用于多个域名的访问该怎么办呢?
  很多时候一套后端的程序都对应了多个调用方,它们使用的的域名不同,scheme 可能也不同。所以 Access-Control-Allow-Origin 的值没法写死一个域名。如果直接暴力地将其设置为「」,可能导致一些未被授权的域名也能请求到资源。而且当 Access-Control-Allow-Credentials 的值为 true 时会导致Access-Control-Allow-Origin 无法被设置为「」。
  正确的玩法应该是在后端程序中获取从 HTTP 请求头传过来的 Origin 字段,然后在程序中验证它的值是否合法,并且做出适当的响应。也就是说,可以不依赖前端的跨域限制,后端如果认为一个请求的 Origin 来自不正确的地方就直接毫不留情地 403 掉。其它情况如果没有 Origin 或者 Origin 正确则将 Origin 的值原原本本地放入 Access-Control-Allow-Origin 中响应回去。
  其实虽然这个问题可以完全通过后端解决,但我还是很费解规范中无法使用局部通配符,和无法配置多个值的设定。也许这么设计的目的就是希望后端直接 403,而不是让浏览器来拦截吧(反正让浏览器来拦截还需要额外的传输成本,有点浪费)

springBoot跨域解决相关推荐

  1. springBoot跨域注解@CrossOrigin

    Spring Framework 4.2 GA为CORS提供了第一类支持,使您比通常的基于过滤器的解决方案更容易和更强大地配置它.所以springMVC的版本要在4.2或以上版本才支持@CrossOr ...

  2. Nginx的简单使用,配置多前端,多端口【微信小程序+前后端分离跨域解决】

    微信小程序 微信小程序需要服务器要有域名,不能有端口,但是我还有一个WebSocket的wss协议路径需要填,都是后台的 示例配置文件,配置https转发http,配置https转发wss user ...

  3. jquery、javascript实现(get、post两种方式)跨域解决方法

     jquery.javascript实现(get.post两种方式)跨域解决方法 一.实现get方式跨域请求数据 浏览器端 <script> $(document).ready(fun ...

  4. JavaScript跨域解决方法大全

    跨域的定义:JavaScript出于安全性考虑,同源策略机制对跨域访问做了限制.域仅仅是通过"URL的首部"字符串进行识别,"URL的首部"指window.lo ...

  5. Nginx跨域解决配置示例

    简介 在日常学习和工作开发中,需要请求两个不同配置的请求经常存在,本文介绍如果还使用Nginx配置解决其跨域问题 相关理论 首先需要了解什么是跨域,下面的两个文章说的很好,请仔细阅读后,然后自己去动手 ...

  6. React项目中请求跨域解决方法

    React项目中请求跨域解决方法 今天经理给我了一个React项目地址,让我拉下来并跑起来,拉下来运行起来后,发现所有的请求都失败了,并且都是由于跨域问题导致的.花了点时间,解决了这个问题,在这里记录 ...

  7. 图片裁剪工具vueCropper跨域解决

    图片裁剪工具vueCropper跨域解决 1.报错原因:本项目的图片放在亚马逊,需求是直接拿到网络图片进行裁剪 2.解决:将图片转化成base64 Vue.prototype.getBase64Img ...

  8. Django中的跨域解决办法 基于后端的跨域解决方案

    Django中的跨域解决办法 基于后端的跨域解决方案 1 何为跨域 在浏览器中,只要发送请求的URL的协议.域名.端口号这三者中的任意一个与当前页面地址的协议.域名.端口号不同,则称之为跨域.当发生这 ...

  9. javascript同源策略和跨域实验及其跨域解决办法

    一.问题提出: 从应用A跳转到应用B,用户在应用B上操作完毕后,关闭页面,是否可以用程序自动刷新应用A窗口,以让用户观察操作效果.如支付宝充值,跳转到各银行界面进行充值,充值完毕后,支付宝页面相关自动 ...

最新文章

  1. HTML5 canvas画图
  2. c++语言编辑简单的计算器,c++编写简单的计算器程序
  3. Python与C之间的相互调用
  4. 生成方法中参数的注释
  5. 走出迷宫(信息学奥赛一本通-T1254)
  6. Selenium webdriver中的xpath定位
  7. mysql c api简单连接池
  8. swagger openapi开放平台 pyhton3.7实现http发送请求,pyhon中代码中发送http请求控制4g物联网开关
  9. 【2012.1.24更新】不要再在网上搜索eclipse的汉化包了!
  10. Dijkstra及其堆优化
  11. 考研_数学二_中值定理_证明题_辅助函数的设法
  12. stm32矩阵键盘c语言程序,stm32矩阵键盘原理图及程序介绍
  13. java识别图片文字_java 实现图片的文字识别
  14. 计算机电子贺卡制作圣诞节,如何制作电子圣诞贺卡?贺卡制作步骤
  15. 常见后端数据存储问题解决方案
  16. 自己动手编译最新Android源码及SDK
  17. C# extention extension
  18. Arduino与Proteus仿真实例-SHT7x温度湿度传感器驱动仿真
  19. 商城运费模板数据库简单设计思路
  20. 审计署计算机中级考试blog,代码审计篇

热门文章

  1. python控制多台手机,用python同时启动多个appium,并让多个手机同时执行脚本
  2. java 多线程基础, 我觉得还是有必要看看的
  3. 16.通过实现“函数一个返回值出口,返回两个返回值”。来了解指针与普通地址的区别...
  4. OLAP和OLTP的区别(基础知识) 【转】
  5. java-前端之js
  6. 云管理不是巴别塔 从数据跨入云之路
  7. 受损虚拟机的修复方法
  8. Visio 与 Access 2007 的集成应用
  9. 自动备份SQL Server数据库中用户创建的Stored Procedures
  10. centos7下安装mysql及测试centos_CentOS7安装mysql8