1. 跨域问题:Java开发者绕不开的坎
第一次遇到跨域问题时,我正在开发一个前后端分离的电商项目。前端用Vue.js跑在8080端口,后端Spring Boot服务在9090端口。当我从前端调用后端API时,浏览器控制台赫然出现红色错误:"Access-Control-Allow-Origin"。那一刻我才明白,跨域不是理论概念,而是每个JavaWeb开发者必须直面的现实问题。
跨域问题源于浏览器的同源策略(Same-Origin Policy),这是现代浏览器最基本的安全机制。简单来说,当协议(http/https)、域名、端口三者有任一不同时,就属于跨域访问。比如:
- http://a.com → https://a.com (协议不同)
- http://a.com → http://b.com (域名不同)
- http://a.com:8080 → http://a.com:9090 (端口不同)
注意:跨域限制是浏览器的行为,服务器之间直接调用不存在此限制。这也是为什么Postman测试接口正常,但浏览器访问就报错的原因。
2. 跨域解决方案全景图
2.1 经典CORS方案
CORS(Cross-Origin Resource Sharing)是W3C标准,也是目前最主流的解决方案。其核心思想是通过HTTP头来告诉浏览器该允许哪些跨域请求。
Spring Boot中实现CORS有三种方式:
- 全局配置(推荐生产环境使用):
@Configuration public class CorsConfig implements WebMvcConfigurer { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") .allowedOrigins("*") // 实际项目应替换为具体前端地址 .allowedMethods("GET", "POST", "PUT", "DELETE") .allowCredentials(true) .maxAge(3600); } }- 控制器注解(适合局部控制):
@RestController @RequestMapping("/api") @CrossOrigin(origins = "http://localhost:8080") public class ApiController { // 控制器方法 }- 过滤器方式(最灵活但需要手动处理):
public class CorsFilter implements Filter { @Override public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { HttpServletResponse response = (HttpServletResponse) res; response.setHeader("Access-Control-Allow-Origin", "*"); // 其他必要头信息设置 chain.doFilter(req, res); } }2.2 代理服务器方案
当不能修改服务端代码时,前端可以通过代理解决跨域。开发环境下常用webpack-dev-server的proxy配置:
// vue.config.js module.exports = { devServer: { proxy: { '/api': { target: 'http://localhost:9090', changeOrigin: true, pathRewrite: { '^/api': '' } } } } }生产环境则可以使用Nginx反向代理:
server { listen 80; server_name yourdomain.com; location /api { proxy_pass http://backend:9090; proxy_set_header Host $host; } }2.3 JSONP的取巧方案
JSONP利用