1 什么事跨域问题?
很多小伙伴第一次遇到跨域问题,大概率会一脸懵逼:“我后端接口明明通了,Postman也能调,为啥浏览器就报红字?”
其实这事儿得怪浏览器的“同源策略”(Same-Origin Policy)。
简单说,浏览器觉得“不同源的请求都是耍流氓”。
比如你的前端跑在http://localhost:8080。
而后端在https://api.xxx.com:8000。
只要协议、域名、端口任何一个不同,就会被浏览器直接掐断。
举个栗子🌰:
// 前端代码(http://localhost:8080)
fetch('http://api.xxx.com:8000/user')
.then(res => res.json())
.then(data => console.log(data));
// 浏览器控制台报错:
// Access to fetch from 'http://localhost:8080' has been blocked by CORS policy...
这时候,你就需要“跨域解决方案”来帮浏览器松绑了!
那么,如何解决跨域问题呢?
2 解决跨域问题的方案
2.1 CORS(跨域资源共享)
适用场景:前后端分离项目、接口需要兼容多种客户端。
CORS是W3C标准,后端只需在响应头里加几个字段,告诉浏览器“这个接口我允许谁访问”。
后端代码示例(Spring Boot版):
// 方法1:直接怼注解(适合单个接口)
@CrossOrigin(origins = "http://localhost:8080")
@GetMapping("/user")
public User getUser() { ... }
// 方法2:全局配置(一劳永逸)
@Configuration
public class CorsConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("http://localhost:8080")
.allowedMethods("*")
.allowedHeaders("*")
.allowCredentials(true)
.maxAge(3600);
}
}
关键响应头:
Access-Control-Allow-Origin: http://localhost:8080(允许的源)
Access-Control-Allow-Methods: GET,POST(允许的方法)
Access-Control-Allow-Credentials: true(允许带Cookie)
注意坑点:
如果用了allowCredentials(true),allowedOrigins不能为*(必须明确指定域名)。
复杂请求(比如Content-Type是application/json)会先发一个OPTIONS预检请求,记得处理!
2.2 JSONP
适用场景:老项目兼容、只支持GET请求(比如调用第三方地图API)。
JSONP利用