跨域问题
- 前后端分离的技术跨域问题是最明显的,根本原因是浏览器受到同源策略的限制,是浏览器行为(请求到达服务器但是返回时被浏览器限制)
- 开发中前端工程使用 webpack 启了一个服务,所以前后端并不在一个端口下,必然涉及到跨域
- 跨域问题的原因是同源策略,也即脚本只能访问相同协议 / 相同主机名 / 相同端口的资源(不同域名端口和协议之间不能共享资源), 如果要突破这个限制, 那就是所谓的跨域, 此时需要遵守 CORS(Cross-Origin Resource Sharing) 机制
- 访问类型为==xhr(XMLHttpRequest)==的才会出现跨域
跨域分类
跨域解决
简单请求 Simple Request
发起的Http请求符合:
- 1.无自定义请求头,
- 2.请求动词为GET、HEAD或POST之一,
- 3.动词为POST时,Content-Type是application/x-www-form-urlencoded,
multipart/form-data或text/plain之一
预检请求 Preflighted Request
发起的Http请求符合其中之一:
- 1.包含了自定义请求头,
- 2.请求动词不是GET、HEAD或POST,
- 3.动词是POST时, Content-Type不是application/x-www-form-urlencoded,
multipart/form-data或text/plain。 即:简单请求的相反
凭证请求 Requests with Credential
发起的Http请求中带有凭证
前端解决方案
- 可以对浏览器设置进行修改解决跨域问题,是一些web安全的配置失效
-
- 使用jsnop解决跨域,让服务端不返回JSON数据返回一段JS代码传入回调函数
后端解决方案
服务器修改
- 可以在基于apache和nginx的服务器的代码上做一定的修改
- 可以做基于nginx的反向代理
CORS
- W3C组织制定了一个Cross-Origin Resource Sharing规范,简写为Cors,现在这个规范已经被大多数浏览器支持处理跨域需求
SpringBoot2.x配置Cors
pringBoot2.x主要提供了两种方式来支持Cors,
- @CrossOrigin注解,作用于一个Controller中全部接口或是其中一个特定的接口用于配置、定制特定的请求接口
- WebMvcConfigurer对象,作用于全部接口,适用于全局配置
使用@CrossOrigin注解
@RestController
@RequestMapping(value = "/api/users")
@CrossOrigin
public class UsersController{
@Autowired
private UsersService usersService;
@PostMapping
@CrossOrigin
public User create(@RequestBody User user) {
return userService.save(user);
}
}
使用WebMvcConfigurer对象
@Configuration
public class MyConfiguration {
@Bean
public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurer() {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/api/**")
.allowedOrigins("*")
.allowCredentials(true)
.allowedMethods("GET", "POST", "DELETE", "PUT","PATCH")
.maxAge(3600);
}
};
}
}
重要的方法类:CorsRegistry (方法名:addMapping),属于SpringBoot配置用于配置支持跨域的路径