Java CORS问题:从DockerHub拉取Spring/MySQL后端进行前端开发
我已经将java/mysql后端应用程序推送到我的私有dockerhub。我想对其进行沙箱处理,以便多个用户可以访问,并对此应用程序进行API调用,因为我们希望在React中进行一些前端浏览器开发。使用诸如Postman之类的REST客户端是可以的,但当我们开始使用浏览器时,就会出现CORS问题:Java CORS问题:从DockerHub拉取Spring/MySQL后端进行前端开发,java,reactjs,spring,docker,docker-compose,Java,Reactjs,Spring,Docker,Docker Compose,我已经将java/mysql后端应用程序推送到我的私有dockerhub。我想对其进行沙箱处理,以便多个用户可以访问,并对此应用程序进行API调用,因为我们希望在React中进行一些前端浏览器开发。使用诸如Postman之类的REST客户端是可以的,但当我们开始使用浏览器时,就会出现CORS问题: Access to fetch at 'http://127.0.0.1:8080/simulations/1/ratings/1' from origin 'http://localhost:300
Access to fetch at 'http://127.0.0.1:8080/simulations/1/ratings/1' from origin 'http://localhost:3000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
我的docker compose.yml
文件如下:
version: '3'
services:
footysim-db:
restart: always
container_name: footysim-db
image: 'mysql:5.7.30'
environment:
MYSQL_ROOT_PASSWORD: password
MYSQL_DATABASE: football_simulation
MYSQL_USER: user
MYSQL_PASSWORD: password
ports:
- '3308:3306'
volumes:
- './initial.sql:/docker-entrypoint-initdb.d/initial.sql'
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
depends_on:
- footysim-db
在Spring Boot的my应用程序属性中:
project.cors.allowedOrigins=http://$server_ip:3000, http://127.0.0.1:3000
我的配置有问题吗?我过去也遇到过类似的问题。但这与docker无关。
作为允许CORS功能的一种变通方法,我添加了一个自定义过滤器,在其中我定义了允许CORS头使用的特定API路径
下面的代码片段:
public class CorsFilter implements Filter {
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
throws IOException, ServletException {
String path = ((HttpServletRequest) req).getServletPath();
if(path.contains("abcd- api path after contextPath ")||path.contains("abcd- api path after contextPath ")) {
HttpServletResponse response = (HttpServletResponse) res;
HttpServletRequest request = (HttpServletRequest) req;
response.setHeader("Access-Control-Allow-Origin", request.getHeader("Origin"));
response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Credentials", "true");
response.setHeader("Access-Control-Allow-Headers", "*");
}
chain.doFilter(req, res);
}
@Override
public void init(FilterConfig filterConfig) {}
@Override
public void destroy() {}
}
谢谢你,伊姆兰。按照同样的思路,我发现这就是解决方案:
@Bean
public CorsConfigurationSource corsConfigurationSource() {
final CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOrigins(ImmutableList.of("*"));
configuration.setAllowedMethods(ImmutableList.of("HEAD",
"GET", "POST", "PUT", "DELETE", "PATCH"));must not be the wildcard '*' when the request's credentials mode is 'include'.
configuration.setAllowCredentials(true);
configuration.setAllowedHeaders(ImmutableList.of("Authorization", "Cache-Control", "Content-Type"));
final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}