HTML 5中新增的跨域资源访问(Cross-Origin Resource Sharing)特性可以让我们在开发后端系统的时候决定资源是否允许被跨域访问。所谓跨域指的是域名不同或者端口不同或者协议不同,比如当从mrbrid.cc网站访问mrbird.cc:8080网站资源就会存在跨域问题。Spring从4.2版本开始就提供了跨域的支持,开箱即用。这里介绍如何在Spring Boot开发中解决跨域的问题,主要分为注解驱动和接口编程的方式。

模拟跨域

要解决跨域问题,我们就得先模拟一个跨域情景。新建Spring Boot项目,版本为2.1.0.RELEASE,并引如下依赖:

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>

项目结构如下所示:

在com.example.demo路径下新建controller包,并创建TestController:

@Controller
public class TestController {

  @RequestMapping("index")
  public String index () {
      return "index";
  }

  @RequestMapping("hello")
  @ResponseBody
  public String hello(){
      return "hello";
  }
}

然后在resources/templates下新建index.html:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>跨域测试</title>
  <script src="http://libs.baidu.com/jquery/1.11.3/jquery.min.js"></script>
</head>
<body>
<div id="hello"></div>
</body>
<script>
  $(function () {
      $.get("http://test.mrbird.cc:8080/hello", function (data) {
          $("#hello").text(data);
      })
  })
</script>
</html>

编辑本地hosts文件,将http://test.mrbird.cc网址映射到127.0.0.1上:

启动项目访问http://localhost:8080/,会发现页面并没有成功显示hello,并且F12观察浏览器控制台会发现其报错了:

这是因为我们在http://localhost:8080/域名下试图访问http://test.mrbird.cc:8080下的hello接口,这就存在跨域问题,接下来我们来解决这个问题。

注解驱动

Spring 4.2后提供了@CrossOrigin注解,该注解可以标注于方法或者类上,包含了以下属性:

属性 含义
value 指定所支持域的集合,*表示所有域都支持,默认值为*。这些值对应HTTP请求头中的Access-Control-Allow-Origin
origins 同value
allowedHeaders 允许请求头中的header,默认都支持
exposedHeaders 响应头中允许访问的header,默认为空
methods 支持请求的方法,比如GETPOSTPUT等,默认和Controller中的方法上标注的一致。
allowCredentials 是否允许cookie随请求发送,使用时必须指定具体的域
maxAge 预请求的结果的有效期,默认30分钟

我们来改造TestController中的hello方法:

@RequestMapping("hello")
@ResponseBody
@CrossOrigin(value = "*")
public String hello() {
  return "hello";
}

表示允许所有域都支持,重启项目,再次访问http://localhost:8080/

接口编程

除了使用@CrossOrigin注解外,我们可以使用接口编程的方式进行统一配置。

com.example.demo路径下新建config包,然后创建WebConfigurer,实现WebMvcConfigurer,重写addCorsMappings默认实现:

@Configuration
public class WebConfigurer implements WebMvcConfigurer {

  @Override
  public void addCorsMappings(CorsRegistry registry) {
      registry.addMapping("/**")
              .allowedOrigins("*")
              .allowedMethods("GET");
  }
}

上面配置表示允许所有请求支持跨域访问,并且不限定域,但是支持持GET方法。将hello方法上的@CrossOrigin注解注释掉,重启项目,再次访问http://localhost:8080/,结果也是OK的。

过滤器实现

查看官方文档,发现其还提供了基于过滤器的实现方式:

@Bean
public FilterRegistrationBean corsFilter() {
  UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
  CorsConfiguration config = new CorsConfiguration();
  config.setAllowCredentials(true);
  config.addAllowedOrigin("*");
  source.registerCorsConfiguration("/**", config);
  FilterRegistrationBean bean = new FilterRegistrationBean(new CorsFilter(source));
  bean.setOrder(0);
  return bean;
}

Actuator跨域

如果项目里集成了Actuator相关功能,其暴露的接口也支持跨域,只需要在配置文件中添加如下配置即可:

ENDPOINTS CORS CONFIGURATION (CorsEndpointProperties)

management.endpoints.web.cors.allow-credentials= # Whether credentials are supported. When not set, credentials are not supported.
management.endpoints.web.cors.allowed-headers= # Comma-separated list of headers to allow in a request. '*' allows all headers.
management.endpoints.web.cors.allowed-methods= # Comma-separated list of methods to allow. '*' allows all methods. When not set, defaults to GET.
management.endpoints.web.cors.allowed-origins= # Comma-separated list of origins to allow. '*' allows all origins. When not set, CORS support is disabled.
management.endpoints.web.cors.exposed-headers= # Comma-separated list of headers to include in a response.
management.endpoints.web.cors.max-age=1800s # How long the response from a pre-flight request can be cached by clients. If a duration suffix is not specified, seconds will be used.

Spring Boot 中处理跨域的更多相关文章

  1. spring boot:解决cors跨域问题的两种方法(spring boot 2.3.2)

    一,什么是CORS? 1,CORS(跨域资源共享)(CORS,Cross-origin resource sharing), 它是一个 W3C 标准中浏览器技术的规范, 它允许浏览器向非同一个域的服务 ...

  2. Java Spring boot 2.0 跨域问题

    跨域 一个资源会发起一个跨域HTTP请求(Cross-site HTTP request), 当它请求的一个资源是从一个与它本身提供的第一个资源的不同的域名时 . 比如说,域名A(http://dom ...

  3. spring boot之配置跨域

    在启动类中配置 @Bean public WebMvcConfigurer corsConfigurer() { return new WebMvcConfigurer() { @Override p ...

  4. spring boot项目配置跨域

    1.在项目启动入口类实现 WebMvcConfigurer 接口: @SpringBootApplication public class Application implements WebMvcC ...

  5. 关于 Spring Security OAuth2 中 CORS 跨域问题

    CORS 是一个 W3C 标准,全称是”跨域资源共享”(Cross-origin resource sharing).它允许浏览器向跨源服务器,发出XMLHttpRequest请求,从而克服了 AJA ...

  6. Spring Boot中通过CORS解决跨域问题

    今天和小伙伴们来聊一聊通过CORS解决跨域问题. 同源策略 很多人对跨域有一种误解,以为这是前端的事,和后端没关系,其实不是这样的,说到跨域,就不得不说说浏览器的同源策略. 同源策略是由Netscap ...

  7. Spring Boot中使用 Spring Security 构建权限系统

    Spring Security是一个能够为基于Spring的企业应用系统提供声明式的安全访问控制解决方案的安全框架.它提供了一组可以在Spring应用上下文中配置的Bean,为应用系统提供声明式的安全 ...

  8. Spring Boot中只能有一个WebMvcConfigurationSupport配置类

    首先将结论写文章的最前面,一个项目中只能有一个继承WebMvcConfigurationSupport的@Configuration类(使用@EnableMvc效果相同),如果存在多个这样的类,只有一 ...

  9. Springboot中关于跨域问题的一种解决方法

    前后端分离开发中,跨域问题是很常见的一种问题.本文主要是解决 springboot 项目跨域访问的一种方法,其他 javaweb 项目也可参考. 1.首先要了解什么是跨域 由于前后端分离开发中前端页面 ...

  10. Spring Boot 中 Redis 的使用

    Spring Boot 对常用的数据库支持外,对 Nosql 数据库也进行了封装自动化,如Redis.MongoDB等,本文主要介绍Redis的使用. Redis 介绍 Redis 是目前业界使用最广 ...

随机推荐

  1. Django-django-celery的配置

    1.安装django-celery   pip install django-celery 2.添加配置 demos/demos/settings.py(我的项目名为demos,这里只是示范,切勿搞混 ...

  2. 实现ViewPager一次滑动多页(保持居中)

    项目中开发日历功能,需求是可以连续滑动多页,有列表的流畅.又要保持当前页居中显示. 参考文献:  http://www.open-open.com/lib/view/open1435026935638 ...

  3. logback-spring.xml配置说明

    logback-spring.xml的配置说明 <?xml version="1.0" encoding="UTF-8"?> <configu ...

  4. excel 巧用功能

    1. 分类汇总 数据-->分类汇总--> 解决问题:解决了我按字段分类并分页打印的问题,例如几十个村数据,要按村分页打印相关数据这时不能把村分别复制粘贴到一个一个工作薄,太麻烦了. 处理方 ...

  5. 关于HTML5语义化

    根据 HTML5 规范,在没有其他合适标签更合适时,才应该把 <b> 标签作为最后的选项. HTML5 规范声明:应该使用 <h1> - <h6> 来表示标题,使用 ...

  6. 域名证书https配置问题

    目前默认通配证书只适配2级通配.例如配置2级域名的通配证书 https://a.baidu.com.如果想配置三级域名的https 需购买3级通配证书.这样才可以配置三级域名. https://a.b ...

  7. 87、linux root 密码忘记了

    子账户登录,然后重置即可

  8. unix:///var/run/supervisor.sock no such file报错解决办法

    报错 unix:///var/run/supervisor.sock no such file 原因 /var/run/supervisor.sock已被清理. 解决办法 关闭supervisor:p ...

  9. Linux详解

    什么是操作系统?1.操作系统:(Operating System,OS)是计算机系统中的一个系统软件,它们管理和控制计算机系统中的硬件及软件资源,为用户提供一个功能强大.使用方便的和可扩展的工作环境. ...

  10. Path类,文件操作的路径用法

    using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Tex ...