一、跨域问题本质

浏览器出于安全考虑执行的同源策略,当前端(http://localhost:8080)访问后端(http://localhost:8888)时,因协议、域名、端口任意一项不同即触发跨域限制,错误表现为:

Access to XMLHttpRequest at 'http://localhost:8888/api' from origin 'http://localhost:8080' has been blocked by CORS policy

二、开发环境解决方案

方案1:Vue3前端代理配置(推荐)

在开发环境中,通过前端脚手架工具代理请求模拟同源访问:

针对Vite项目 (vite.config.js):

<JAVASCRIPT>

export default defineConfig({
  server: {
    proxy: {
      '/api': {
        target: 'http://localhost:8888',  // Spring Boot后端地址
        changeOrigin: true,               // 虚拟托管
        rewrite: (path) => path.replace(/^\/api/, '') // 路径重写(可选)
      }
    }
  }
})
针对Vue CLI项目 (vue.config.js):

<JAVASCRIPT>

module.exports = {
  devServer: {
    proxy: {
      '/api': {
        target: 'http://localhost:8888',
        changeOrigin: true,
        pathRewrite: { '^/api': '' }
      }
    }
  }
}

调用示例

<JAVASCRIPT>

axios.get('/api/users')  // 实际代理到 http://localhost:8888/users

方案2:Spring Boot后端CORS配置

在Spring Boot中添加全局CORS配置,允许特定客户端访问:

<JAVA>

@Configuration
public class CorsConfig implements WebMvcConfigurer {
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")  // 匹配所有路径
                .allowedOrigins("http://localhost:8080")  // Vue前端地址
                .allowedMethods("GET", "POST", "PUT", "DELETE")
                .allowedHeaders("*")
                .allowCredentials(true);  // 允许携带cookie
    }
}

注意:如使用Spring Security,需额外配置:

<JAVA>

@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.cors()  // 启用Spring Security CORS
            .and()
            // 其他安全配置...
    }
}

三、生产环境解决方案

生产环境不再使用本地代理,推荐通过统一部署域名 + Nginx反向代理解决跨域问题:

Nginx统一反向代理配置

<NGINX>

server {
    listen       80;
    server_name  your-domain.com;

    # 前端静态文件服务
    location / {
        root   /usr/share/nginx/html;
        index  index.html;
        try_files $uri $uri/ /index.html;  # 支持Vue Router history模式
    }

    # 后端接口代理转发
    location /api/ {
        proxy_pass  http://backend-server:8888/;  # 后端服务真实地址
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}

此时前端和后端通过统一域名访问,规避跨域问题(如 https://your-domain.com)。


四、可选补充方案

1. Spring Boot单控制器CORS注解

<JAVA>

@RestController
@CrossOrigin(origins = "http://localhost:8080")  // 指定控制器允许的源
@RequestMapping("/api")
public class UserController {
    // 接口方法...
}
2. 自定义CORS过滤器

处理复杂场景(如动态校验Origin):

<JAVA>

@Component
public class CustomCorsFilter implements Filter {
    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) 
        throws IOException, ServletException {
        HttpServletResponse response = (HttpServletResponse) res;
        HttpServletRequest request = (HttpServletRequest) req;

        response.setHeader("Access-Control-Allow-Origin", "http://localhost:8080");
        response.setHeader("Access-Control-Allow-Methods", "GET,POST,PUT,DELETE");
        response.setHeader("Access-Control-Allow-Headers", "*");

        if ("OPTIONS".equalsIgnoreCase(request.getMethod())) {
            response.setStatus(HttpServletResponse.SC_OK);
            return;
        }

        chain.doFilter(req, res);
    }
}

五、验证与调试

  1. 浏览器F12检查请求头

    • 确认前端请求地址是否代理到正确后端地址
    • 检查OriginAccess-Control-Allow-Origin头是否匹配
  2. 跨域错误模拟工具

    <JAVASCRIPT>

    // 在前端直接请求后端地址(非代理方式)
    axios.get('http://localhost:8888/api/users').then(...)

    若配置成功应可正常响应,反之会触发跨域错误。

  3. 生产环境验证: 通过curl命令或Postman模拟跨域请求:

    curl -H "Origin: http://your-domain.com" -I http://api.your-domain.com/users
    

六、安全注意事项

  1. 避免使用通配符*:生产环境应限定具体的allowedOrigins
  2. 结合HTTPS:确保跨域请求通过加密传输
  3. 鉴权与CSRF保护:携带Cookie时需同步解决CSRF问题

通过上述配置,Vue3 + Spring Boot项目的跨域问题将在开发和生产环境中得到完整解决。

Logo

技术共进,成长同行——讯飞AI开发者社区

更多推荐