Springboot跨域问题,是当前主流web开发人员都绕不开的难题。但我们首先要明确以下几点
- 跨域只存在于浏览器端,不存在于安卓/ios/Node.js/python/ java等其它环境
- 跨域请求能发出去,服务端能收到请求并正常返回结果,只是结果被浏览器拦截了。
- 之所以会跨域,是因为受到了同源策略的限制,同源策略要求源相同才能正常进行通信,即协议、域名、端口号都完全一致。

浏览器出于安全的考虑,使用 XMLHttpRequest对象发起 HTTP请求时必须遵守同源策略,否则就是跨域的HTTP请求,默认情况下是被禁止的。换句话说,浏览器安全的基石是同源策略。

同源策略限制了从同一个源加载的文档或脚本如何与来自另一个源的资源进行交互。这是一个用于隔离潜在恶意文件的重要安全机制。

报错内容:

什么是CORS?
  CORS是一个W3C标准,全称是”跨域资源共享”(Cross-origin resource sharing),允许浏览器向跨源服务器,发出XMLHttpRequest请求,从而克服了AJAX只能同源使用的限制。
  它通过服务器增加一个特殊的Header[Access-Control-Allow-Origin]来告诉客户端跨域的限制,如果浏览器支持CORS、并且判断Origin通过的话,就会允许XMLHttpRequest发起跨域请求。

CORS Header

  • Access-Control-Allow-Origin: http://www.xxx.com
  • Access-Control-Max-Age:86400
  • Access-Control-Allow-Methods:GET, POST, OPTIONS, PUT, DELETE
  • Access-Control-Allow-Headers: content-type
  • Access-Control-Allow-Credentials: true

含义解释:

CORS Header属性 解释
Access-Control-Allow-Origin 允许http://www.xxx.com域(自行设置,这里只做示例)发起跨域请求
Access-Control-Max-Age 设置在86400秒不需要再发送预校验请求
Access-Control-Allow-Methods 设置允许跨域请求的方法
Access-Control-Allow-Headers 允许跨域请求包含content-type
Access-Control-Allow-Credentials 设置允许Cookie

解决Springboot的CORS跨域问题

方法一、直接采用SpringBoot的注解@CrossOrigin(也支持SpringMVC)
简单粗暴的方式,Controller层在需要跨域的类或者方法上加上该注解即可

/*** Created with IDEA** @Author Chensj* @Date 2020/5/8 10:28* @Description xxxx控制层* @Version 1.0*/
@RestController
@CrossOrigin
@RequestMapping("/situation")
public class SituationController extends PublicUtilController {@Autowiredprivate SituationService situationService;// log日志信息private static Logger LOGGER = Logger.getLogger(SituationController.class);}

但每个Controller都得加,太麻烦了,怎么办呢,加在Controller公共父类(PublicUtilController)中,所有Controller继承即可。

/*** Created with IDEA** @Author Chensj* @Date 2020/5/6 10:01* @Description* @Version 1.0*/
@CrossOrigin
public class PublicUtilController {/*** 公共分页参数整理接口** @param currentPage* @param pageSize* @return*/public PageInfoUtil proccedPageInfo(String currentPage, String pageSize) {/* 分页 */PageInfoUtil pageInfoUtil = new PageInfoUtil();try {/** 将字符串转换成整数,有风险, 字符串为a,转换不成整数*/pageInfoUtil.setCurrentPage(Integer.valueOf(currentPage));pageInfoUtil.setPageSize(Integer.valueOf(pageSize));} catch (NumberFormatException e) {}return pageInfoUtil;}}

当然,这里虽然指SpringBoot,SpringMVC也是同样的,但要求在Spring4.2及以上的版本。另外,如果SpringMVC框架版本不方便修改,也可以通过修改tomcat的web.xml配置文件来处理,请参照另一篇博文(nginx同理)

SpringMVC使用@CrossOrigin使用场景要求
  jdk1.8+
  Spring4.2+

方法二、处理跨域请求的Configuration
  增加一个配置类,CrossOriginConfig.java。继承WebMvcConfigurerAdapter或者实现WebMvcConfigurer接口,其他都不用管,项目启动时,会自动读取配置。

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;/*** AJAX请求跨域* @author Mr.W* @time 2018-08-13*/
@Configuration
public class CorsConfig extends WebMvcConfigurerAdapter {static final String ORIGINS[] = new String[] { "GET", "POST", "PUT", "DELETE" };@Overridepublic void addCorsMappings(CorsRegistry registry) {registry.addMapping("/**").allowedOrigins("*").allowCredentials(true).allowedMethods(ORIGINS).maxAge(3600);}

另一种写法

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class CorsConfig implements WebMvcConfigurer {@Overridepublic void addCorsMappings(CorsRegistry registry) {registry.addMapping("/**").allowedOrigins("*").allowedMethods("GET", "HEAD", "POST", "PUT", "DELETE", "OPTIONS").allowCredentials(true).maxAge(3600).allowedHeaders("*");}
}

这种方式是全局配置的,网上也大都是这种解决办法,但是很多都是基于旧的spring版本,比如:
https://blog.csdn.net/tiangongkaiwu152368/article/details/81099169

方法三、采用过滤器(filter)的方式
  同方法二加配置类,增加一个CORSFilter 类,并实现Filter接口即可,其他都不用管,接口调用时,会过滤跨域的拦截。

 @Component
public class CORSFilter implements Filter {@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)throws IOException, ServletException {HttpServletResponse res = (HttpServletResponse) response;res.addHeader("Access-Control-Allow-Credentials", "true");res.addHeader("Access-Control-Allow-Origin", "*");res.addHeader("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT");res.addHeader("Access-Control-Allow-Headers", "Content-Type,X-CAF-Authorization-Token,sessionToken,X-TOKEN");if (((HttpServletRequest) request).getMethod().equals("OPTIONS")) {response.getWriter().println("ok");return;}chain.doFilter(request, response);}@Overridepublic void destroy() {}@Overridepublic void init(FilterConfig filterConfig) throws ServletException {}
}
@Configuration
public class CorsFilterConfig {@Beanpublic CorsFilter corsFilter() {// 1.添加CORS配置信息CorsConfiguration config = new CorsConfiguration();// 放行哪些原始域config.addAllowedOrigin("*");// 是否发送Cookie信息config.setAllowCredentials(true);// 放行哪些原始域(请求方式)config.addAllowedMethod("*");// 放行哪些原始域(头部信息)config.addAllowedHeader("*");// 暴露哪些头部信息(因为跨域访问默认不能获取全部头部信息)config.addExposedHeader("*");// 2.添加映射路径导入配置UrlBasedCorsConfigurationSource configSource = new UrlBasedCorsConfigurationSource();configSource.registerCorsConfiguration("/**", config);// 3.返回新的CorsFilter.return new CorsFilter(configSource);}
}

方法四、采用nginx做动态代理
使用nginx作为代理,解决跨域问题

1)更改前端ajax访问路径:不直接访问请求接口,而是访问另外一个本域下的接口,例如:http://kuayu.com/getCat

2)修改nginx配置文件:

location /getCat { #添加访问目录为/getCatrewrite  ^/getCat/(.*)$ /$1 break;proxy_pass   http://csdn.b.com/cat/;}

方法五、 手动设置响应头(局部跨域)
使用 HttpServletResponse 对象添加响应头(Access-Control-Allow-Origin)来授权原始域,这里 Origin的值也可以设置为 “*”,表示全部放行。

@RequestMapping("/index")
public String index(HttpServletResponse response) {response.addHeader("Access-Allow-Control-Origin","*");return "index";
}

CORS跨域问题原因和解决方案相关推荐

  1. 前端跨域问题原因及解决方案

    跨域是如何形成的? 当我们请求一个url的 协议.域名.端口三者之间任意一个与当前页面url的协议.域名.端口 不同这种现象我们把它称之为跨域 跨域会导致: 1.无法读取非同源网页的 Cookie.L ...

  2. 跨域的原因以及解决方案

    # 为什么会产生跨域问题 浏览器限制,目前所有浏览器都实现了同源策略规范. 请求方式Type为xhr.如果非xhr,如json,script则也不会存在跨域问题 请求方与服务方的源不同,即跨域,包括: ...

  3. 不同版本浏览器前端标准兼容性对照表以及CORS解决跨域和CSRF安全问题解决方案

    CORS也已经成为主流的跨域解决方案,不过CORF也会引发CSRF,本文先分享第三方的一个前端工具箱全面展示那些浏览器版本支持CORS,由于各家浏览器厂商因为各自原因在不同的版本里支持的标准不同,这个 ...

  4. CORS 跨域解决方案

    CORS 跨域解决方案 跨源资源共享 跨源资源共享(CORS,或通俗地译为跨域资源共享)是一种基于 HTTP 头的机制,该机制通过允许服务器标示除了它自己以外的其它源(域.协议和端口),使得浏览器允许 ...

  5. CORS跨域实现思路及相关解决方案

    CORS跨域实现思路及相关解决方案 参考文章: (1)CORS跨域实现思路及相关解决方案 (2)https://www.cnblogs.com/safoie/p/10547788.html 备忘一下.

  6. CORS 跨域 实现思路及相关解决方案(转:http://www.cnblogs.com/sloong/p/cors.html)

    本篇包括以下内容: CORS 定义 CORS 对比 JSONP CORS,BROWSER支持情况 主要用途 Ajax请求跨域资源的异常 CORS 实现思路 安全说明 CORS 几种解决方案 自定义CO ...

  7. CORS 跨域 实现思路及相关解决方案

    CORS 跨域 实现思路及相关解决方案 参考文章: (1)CORS 跨域 实现思路及相关解决方案 (2)https://www.cnblogs.com/sloong/p/cors.html 备忘一下.

  8. SpringBoot—CORS跨域问题详解和解决方案

    关注微信公众号:CodingTechWork,一起学习进步. 引言   在前后端开发过程中,遇到过一种错误,类似于报错: Access to XMLHttpRequest at 'http://127 ...

  9. php cros跨域处理,CORS跨域问题解决方案

    跨域问题主要是由于浏览器同源策略限制引起,简单来说,就是只相信自己人,不相信外人,只响应同域名发来的http请求,不相信其他域名发来的http请求.好处是减少上当受骗的几率,缺点是不符合webapi的 ...

最新文章

  1. 单行文字垂直/水平跑马灯效果
  2. ubuntu mysql登陆_ubuntu mysql 配置 远程登陆
  3. 怎样测试运算放大器的输入失调电压?
  4. linux /etc/hosts.allow和/etc/hosts.deny 限制 禁止 ip连接 黑名单 白名单
  5. VTK:饼形图用法实战
  6. dockerfile的详细介绍
  7. python--从入门到实践--chapter 9 类
  8. 事务超时时间无效_什么是ZooKeeper?ZooKeeper分布式事务详解
  9. ES6-Set集合的创建
  10. Ruby on Rails,创建模型,附赠模型与表名不一致时的解决方法
  11. Python day17 模块介绍1(time,random)
  12. CnForums1.0 Alpha RC1 发布
  13. CentOS 7 linux bridge 配置vlan
  14. 将Altera FPGA的sof文件和NIOS II的elf固件合并为一个jic文件以使用Quartus Programmer烧写
  15. eclipse adt离线安装
  16. linux如何设置环境变量
  17. 关于苹果手机页面中字体大小显示不正确的问题
  18. 中学计算机课小课题,中学信息技术课题题目
  19. 软件首次亮相前超级账本技术升温
  20. ChatGPT的前世今生

热门文章

  1. 互联网晚报| 5月20日 星期五 |小鹏汽车被曝毁约20余名应届生;茅台冰淇淋39元一份 ;字节回应游戏发行业务线裁员80%传闻...
  2. 【圈子】提升支付宝芝麻信用评分
  3. JAVA 8 Stream 集合的基本
  4. 19年9月2日汉川出差代码汇总
  5. 解决Mac Big Sur系统无权限Install Adobe安装包
  6. python成绩转换_PYTHON将成绩从百分制变换到等级制
  7. mfc全屏并且物件等比例缩放
  8. CSP 2021考前每日2题(09-24)洛谷P1043 数字游戏 + P3958 奶酪
  9. 荣耀7android正在升级,翻转后摄设计 干掉前摄:华为注册摄像头新专利,升级版荣耀7i或在未来面世...
  10. 2012法定节假日安排,2012春节放假通知,2012元旦放假通知