03_跨域问题解决

03_跨域问题解决

一、跨域简介

**跨域(Cross-Origin)**是浏览器基于"同源策略(Same-Origin Policy)"的一种安全机制。当网页试图访问不同源(域名、协议、端口任一不同)的资源时,浏览器会默认阻止该请求。

✅ 什么是"同源"?

两个页面的协议、域名和端口号完全相同,才称为同源:

URL 是否同源
http://a.com/index.htmlhttp://a.com/api ✅ 同源
http://a.comhttps://a.com ❌ 协议不同
http://a.comhttp://b.com ❌ 域名不同
http://a.com:8080http://a.com:80 ❌ 端口不同
🧨 常见跨域场景
  1. 本地页面调用测试服务器,只在项目开发阶段会有跨域问题。(比较简单)

  2. 使用 header 头提交自定义请求头,会触发浏览器更严格的跨域检查机制,产生的跨域问题。(比较常见+通用,推荐使用)

  3. 使用第三方 Cookie 提交 token,产生的跨域问题。(最古老的方案,目前新版浏览器对此方案限制越来越严格,非必要不选择此方案,如果对此方案不是很熟悉就贸然使用也容易出现安全问题)

二、解决方案

2.1 跨域情形一:只在项目开发阶段会有跨域问题

有些公司项目的开发方式为:

  • 在项目开发时:使用本地页面调用测试服务器接口。(域名不同,存在跨域问题)
  • 在项目部署时:将后端接口和前端页面部署在同一域名下。(域名一致,不存在跨域问题)

这种情况下比较好解决,在代码层面我们无需任何更改,只在前端客户端做出一定的更改就行了。比如说:在前端配置一个代理服务器,或者修改一下 Chrome 客户端使其去除跨域限制。

具体的方案有很多,大家可参考这篇博客:手把手教你解决web前端跨域问题

2.2 跨域情形二:使用 header 头提交 token,产生的跨域问题(比较常见+通用,推荐使用)
2.2.1 Spring Boot 中配置 CORS

🔧 方式一:全局配置(Spring MVC 提供的 CORS 配置方式,依赖 WebMvcConfigurer。)

java 复制代码
@Configuration
public class CorsConfig implements WebMvcConfigurer {
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**") // 允许所有路径
                .allowedOrigins("*") // 允许所有来源(生产建议具体配置)
                .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")
                .allowedHeaders("*")
                .allowCredentials(true) // 允许携带 Cookie
                .maxAge(3600); // 1小时内不用重复 preflight
    }
}

🛠 方式二:Filter 全局拦截配置(更底层)

适合对所有请求路径、静态资源、异常页等统一处理跨域,适用于更复杂场景(如 Spring Security、Filter 链前)。

复制代码
java复制编辑@Configuration
public class CorsConfig {
    @Bean
    public CorsFilter corsFilter() {
        CorsConfiguration config = new CorsConfiguration();

        config.addAllowedOriginPattern("*"); // 所有来源(开发环境使用)
        // config.addAllowedOriginPattern("http://yourdomain.com"); // 生产建议明确域名

        config.setAllowCredentials(true); // 允许凭证(Cookie)
        config.addAllowedMethod("*");     // 所有请求方法
        config.addAllowedHeader("*");     // 所有请求头
        config.addExposedHeader("Authorization"); // 暴露授权头
        config.setMaxAge(3600L);          // 预检缓存 1 小时

        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", config); // 所有路径

        return new CorsFilter(source);
    }
}

🚀 方式三:注解方式(适合少数接口需要跨域)

java 复制代码
@CrossOrigin(origins = "http://localhost:3000")
@RestController
@RequestMapping("/api")
public class DemoController {
    @GetMapping("/hello")
    public String hello() {
        return "Hello World!";
    }
}

❗总结对比:

项目 方式一(WebMvcConfigurer) 方式二(Filter)
配置粒度 仅 Spring MVC 接口请求 全局、所有请求
实现机制 Spring MVC 配置 Servlet 过滤器(Filter)
生效范围 仅 Controller 映射路径 包括静态资源、错误页面、控制器等
执行顺序 相对较晚 更早(在 Spring Security 等之前)
2.2.2 SaToken 中配置 CORS(依赖 WebMvcConfigurer。)
java 复制代码
/**
 * [Sa-Token 权限认证] 配置类 
 *
 * @author click33
 */
@Configuration
public class SaTokenConfigure implements WebMvcConfigurer {

	/**
	 * CORS 跨域处理策略
	 */
	@Bean
	public SaCorsHandleFunction corsHandle() {
		return (req, res, sto) -> {
			res.
				// 允许指定域访问跨域资源
				setHeader("Access-Control-Allow-Origin", "*")
				// 允许所有请求方式
				.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE")
				// 有效时间
				.setHeader("Access-Control-Max-Age", "3600")
				// 允许的header参数
				.setHeader("Access-Control-Allow-Headers", "*");

			// 如果是预检请求,则立即返回到前端
			SaRouter.match(SaHttpMethod.OPTIONS)
				.free(r -> System.out.println("--------OPTIONS预检请求,不做处理"))
				.back();
		};
	}
}
相关推荐
有梦想的骇客2 小时前
书籍“之“字形打印矩阵(8)0609
java·算法·矩阵
yours_Gabriel2 小时前
【java面试】微服务篇
java·微服务·中间件·面试·kafka·rabbitmq
hashiqimiya4 小时前
android studio中修改java逻辑对应配置的xml文件
xml·java·android studio
liuzhenghua664 小时前
Python任务调度模型
java·运维·python
結城5 小时前
mybatisX的使用,简化springboot的开发,不用再写entity、mapper以及service了!
java·spring boot·后端
小前端大牛马5 小时前
java教程笔记(十一)-泛型
java·笔记·python
Bruk.Liu5 小时前
《Minio 分片上传实现(基于Spring Boot)》
前端·spring boot·minio
东阳马生架构5 小时前
商品中心—2.商品生命周期和状态的技术文档
java
星辰离彬5 小时前
Java 与 MySQL 性能优化:MySQL 慢 SQL 诊断与分析方法详解
java·spring boot·后端·sql·mysql·性能优化
q_19132846955 小时前
基于Springboot+Vue的办公管理系统
java·vue.js·spring boot·后端·intellij idea