0%

跨域请求

前端请求和后端相应是开发中十分重要的部分。对于前端请求,因为浏览器的设定,不允许跨域请求。对于后端响应,无论是RestFul风格还是异步请求,都需要把数据转换成Json放入响应体中。
针对上述两点,本文记录了跨域请求的实现以及将响应数据放入响应体中的方法。

前端跨域请求

所谓禁止跨域是指使用 XMLHttpRequest对象发起 HTTP请求时必须遵守同源策略,即:协议、域名、端口号都完全一致。
因为禁止跨域请求是浏览器出于安全考虑的限制,此问题只会出现在浏览器请求的场景。 我们通常使用CORS解决跨域问题,在SpringBoot中可以有两种方式实现,下面展开描述。

使用@CrossOrigin注解

通过查看此注解的源代码发现,此注解可以用于方法上。此注解可以让被其修饰的类或方法内的请求实现跨域。

代码实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
@RestController
@RequestMapping("/user")
@CrossOrigin
// 此类中的请求都允许跨域
public class UserController {

@Autowired
private UserServcie userServcie;

@RequestMapping("/findAll")
public ResponseResult findAll(){
//调用service查询数据 ,进行返回
List<User> users = userServcie.findAll();
return new ResponseResult(200,users);
//此处的 ResponseResult 是为了实现“响应格式统一”参看对应笔记
}
}

使用 WebMvcConfigurer 的 addCorsMappings 方法配置CorsInterceptor

此方法简单的来说就是,创建一个实现类实现 WebMvcConfigurer 接口,重写它的 addCorsMappings 方法来配置CorsInterceptor(Cors拦截器)。

查阅SpringBoot的文档,我们看到了文档中提供了一个匿名内部类的方式实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration(proxyBeanMethods = false)
public class MyCorsConfiguration {

@Bean
public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurer() {

@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/api/**");
//....写其他配置....
}

};
}

}

事实上在开发中,我们更常使用的方式是 创建一个 CorsConfig 的类实现 WebMvcConfigurer 接口,而不是使用匿名内部类。代码示例如下:

代码示例(常用):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
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 {

@Override
public void addCorsMappings(CorsRegistry registry) {
// 设置允许跨域的路径
registry.addMapping("/**")
// 设置允许跨域请求的域名
.allowedOriginPatterns("*")
// 是否允许cookie
.allowCredentials(true)
// 设置允许的请求方式
.allowedMethods("GET", "POST", "DELETE", "PUT")
// 设置允许的header属性
.allowedHeaders("*")
// 跨域允许时间
.maxAge(3600);
}
}

PS:我们通常会创建一个 config 的包放置这个类。加上 @Configuration 这个注解把这个类注入容器