从DockerHub拉取Spring/MySQL后端做前端开发的CORS问题排查
解决Spring Boot + Docker环境下的CORS跨域问题
从你的描述和配置来看,问题核心是CORS配置没有正确生效,主要有几个关键点需要修正:
1. 配置属性的语法错误
你的application-properties里的配置存在两个小问题:
- Spring Boot的变量引用语法是
${变量名},而非$变量名,所以$server_ip应该改成${server_ip} - 允许的源列表里,逗号后的空格会导致解析错误(CORS源不能包含空格),需要去掉空格
修正后的配置应为:
project.cors.allowedOrigins=http://${server_ip}:3000,http://127.0.0.1:3000
2. Docker环境未注入server_ip变量
你在配置里用到了${server_ip},但当前的docker-compose.yml里没有给footysim-server服务传递这个环境变量,导致Spring无法解析该值,最终允许的源变成了包含${server_ip}的无效字符串。
需要在docker-compose.yml的footysim-server服务的environment块中添加这个变量:
footysim-server: restart: always image: 'DOCKERHUB:PROJECT' expose: - '8080' ports: - '8080:8080' environment: SPRING_DATASOURCE_URL: jdbc:mysql://footysim-db:3306/football_simulation?useSSL=false&allowPublicKeyRetrieval=true SPRING_DATASOURCE_USERNAME: user SPRING_DATASOURCE_PASSWORD: password server_ip: 127.0.0.1 # 本地测试填这个;远程服务器替换为公网IP depends_on: - footysim-db
另外注意:SPRING_DATASOURCE_URL里的&是HTML转义字符,在YAML中直接写&即可,无需转义。
3. 确保Spring Boot正确应用CORS配置
仅仅定义配置属性是不够的,你需要在代码中配置CORS过滤器来读取这些属性并生效。可以创建一个全局CORS配置类:
import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.cors.CorsConfiguration; import org.springframework.web.cors.UrlBasedCorsConfigurationSource; import org.springframework.web.filter.CorsFilter; @Configuration public class CorsConfig { @Value("${project.cors.allowedOrigins}") private String allowedOrigins; @Bean public CorsFilter corsFilter() { UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); CorsConfiguration config = new CorsConfiguration(); // 允许携带Cookie(若API需要认证则开启) config.setAllowCredentials(true); // 分割配置里的允许源,处理可能存在的空格 for (String origin : allowedOrigins.split(",")) { config.addAllowedOrigin(origin.trim()); } // 允许所有请求头和请求方法 config.addAllowedHeader("*"); config.addAllowedMethod("*"); // 对所有接口应用CORS配置 source.registerCorsConfiguration("/**", config); return new CorsFilter(source); } }
4. 验证配置是否生效
修改后重新构建镜像并启动服务,然后用curl发送预请求(OPTIONS)验证响应头:
curl -X OPTIONS http://127.0.0.1:8080/simulations/1/ratings/1 -H "Origin: http://localhost:3000" -v
如果响应头中出现Access-Control-Allow-Origin: http://localhost:3000,说明配置已生效,此时浏览器就能正常调用API了。
为什么Postman调用正常?因为Postman不会像浏览器那样发送CORS预请求(OPTIONS),也不会严格校验跨域响应头,所以能正常请求,但浏览器会严格遵循CORS规则,因此必须确保配置正确。
内容的提问来源于stack exchange,提问作者clattenburg cake
相关产品推荐
相关产品推荐

