浅谈前后端分离项目中的跨域问题
1、跨域
1.1 什么是域
域可以简单理解为互联网中的某块地方的地址,有了这个地址就可以访问存放在那块地方的资源。
域由三部分组成:协议名、主机名、端口号。例如http://www.baidu.com:80, 协议名为http,主机名为 www.baidu.com, 端口号为80。
1.2 CORS(跨域源资源共享)
跨源资源共享 (CORS,Cross-origin resource sharing)是一种基于 HTTP 头的机制,该机制通过允许服务器标示除了它自己以外的其它 origin(域,协议和端口),使得浏览器允许这些 origin 访问加载自己的资源。
1.3 什么是跨域
在了解什么是跨域的时候,我们首先要了解一个概念,叫同源策略,什么是同源策略呢,就是我我们的浏览器出于安全考虑,只允许与本域下的接口交互。不同源的客户端脚本在没有明确授权的情况下,不能读写对方的资源。
所以只要域的三个组成部分有至少一个不同时,就会产生跨域问题。例如,域A:http://www.baidu.com:80 和 域B:ftp://www.baidu.com:8080, 两个域的协议名和端口号不同,当域A请求读写域B的资源时就会出现跨域问题。
2、前后端联调中遇到的问题实际遇到的问题
当发生跨域时,浏览器会出现以下错误
Access to XMLHttpRequest at 'http://localhost:3000/api/userlogin' from origin 'http://localhost:8080' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
我的前端页面http://localhost:8080 请求后台http://localhost:3000/api/userlogin 接口,由于端口号不一致而违反了同源策略,响应被浏览器拦截。
3、 解决方案(后端)
3.1 使用@CrossOrigin注解配置某一个方法接受某一个域的请求
@RestController
@Api(tags = "用户")
@Slf4j
public class UserController {
@CrossOrigin(origins = "http://localhost:8080", maxAge = 1800)
@RequestMapping("/userlogin")
public R userLogin(@RequestBody UserLoginInfo userLoginInfo) {
return success(userLoginInfo, "登录成功!");
}
}
在某个方法前加@CrossOrigin注解使得该方法能够被参数指定的域访问。
参数 origins :能够被跨域请求的域。( * 表示所有域)
参数 maxAge : 准备响应前的缓存持续的最大时间(以秒为单位)。
当然也可以在类上加上@CrossOrigin注解使得该类的所有方法都能被跨域访问。
3.2 全局配置
@Configuration
public class CrossOriginConfiguration implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")//匹配的请求路径
.allowedOrigins("*")//被允许的域
.allowedMethods("*")//请求的方法,例如POST,GET,PUT等
.allowedHeaders("*")
.maxAge(1800);
}
}
文章评论