【问题标题】:Request has been blocked by CORS policy even if the CORS setup is done即使 CORS 设置完成,请求也已被 CORS 策略阻止
【发布时间】:2021-07-26 15:46:23
【问题描述】:

在我使用 Jersey 的 Spring Boot 应用程序中,我有以下 cors 过滤器设置:

@Provider
@Component
@ConfigurationProperties(prefix = "admin")
public class CorsFilter implements ContainerResponseFilter {

    private static final Logger LOGGER = LogManager.getLogger(CorsFilter.class);

    private List<String> accessControlAllowOrigin;

    @Override
    public void filter(ContainerRequestContext containerRequestContext, ContainerResponseContext containerResponseContext) {
        allowAccessOrigin(containerRequestContext, containerResponseContext);
        containerResponseContext.getHeaders().add(HttpHeaders.ACCESS_CONTROL_ALLOW_HEADERS, "origin, content-type, accept, authorization");
        containerResponseContext.getHeaders().add(HttpHeaders.ACCESS_CONTROL_ALLOW_CREDENTIALS, "true");
        containerResponseContext.getHeaders().add(HttpHeaders.ACCESS_CONTROL_ALLOW_METHODS, "GET, POST, PUT, DELETE, OPTIONS, HEAD");
    }

    // it sets the origin from the header if the setup contains '*' or the exact same origin from the request headers
    private void allowAccessOrigin(ContainerRequestContext containerRequestContext, final ContainerResponseContext containerResponseContext) {
        accessControlAllowOrigin.stream().filter(allowedOrigin -> 
                allowedOrigin.equals("*") 
                || allowedOrigin.equals(containerRequestContext.getHeaders().getFirst(HttpHeaders.ORIGIN))
            .findFirst().ifPresent(
                allowedOrigin -> containerResponseContext.getHeaders().add(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN, containerRequestContext.getHeaders().getFirst(HttpHeaders.ORIGIN)));
    }

    public List<String> getAccessControlAllowOrigin() {
        return accessControlAllowOrigin;
    }

    public void setAccessControlAllowOrigin(List<String> accessControlAllowOrigin) {
        this.accessControlAllowOrigin = accessControlAllowOrigin;
    }

}

application.yml 包含这样的“admin”配置:

admin:
  access-control-allow-origin:
    - "http://10.8.235.222:4200"
    - "http://localhost:4200"

对于我这样设置的球衣:

@Component
public class JerseyConfig extends ResourceConfig {

    public JerseyConfig() {
        packages("com.my.app.ws.endpoint");
        register(CorsFilter.class);
    }

}

当我调用注册包中的端点时,类似这样:

@Controller
@Path("/user")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public class UserEndPoint {

    private static final Logger LOGGER = LogManager.getLogger(UserCandidatesEndPoint.class);

    @Context
    UriInfo uriInfo;

    private final UserService userService;

    public UserEndPoint(final UserService userService) {
        this.userService = userService;
    }

    @GET
    @Path(/{userEmail})
    @Consumes({MediaType.TEXT_PLAIN, MediaType.APPLICATION_JSON})
    public Response getUserCandidate(@PathParam("userEmail") final String userEmail) {
        UserDto user = userService.getUserByEmail(userEmail);
        return Response.ok().entity(user).build();
    }
}

如果我用邮递员测试 api,它工作正常!

如果我使用浏览器通过 Angular 应用程序连接,我会收到以下错误:

访问 XMLHttpRequest 在 来自原产地的“http://10.8.235.222:8081/myapp/user/jo@gmail.com” “http://localhost:4200”已被 CORS 策略阻止:响应 预检请求未通过访问控制检查:它没有 HTTP 正常状态。

我还缺少什么?

我没有 Spring Security,所以我需要使用 Jersey 进行设置。

【问题讨论】:

  • 你试过代理吗? angular.io/guide/build,这里有一个在angular中配置代理conf的指南
  • 1.您的代码无法编译;你少了一个括号。 2. 错误消息显示“它没有 HTTP ok 状态。” - 请参阅this post

标签: angular spring-boot browser cors jersey


【解决方案1】:

很可能是您的浏览器阻止了这些请求。您可以使用浏览器的开发人员工具进行检查。控制台上的某处是否说浏览器阻止了它?

对于本地开发,我建议您配置代理如下:

src/app/proxy.conf.json:

{
    "/api/*": {
        "target": "http://localhost:_YOUR_BACKEND_PORT_",
        "secure": false
    }
}

那么,在你的angular.json

                ...
                "serve": {
                    "builder": "@angular-devkit/build-angular:dev-server",
                    "options": {
                        "browserTarget": "your-app:build",
                        "proxyConfig": "src/proxy.conf.json"
                    },
                    ...

然后,确保在本地开发时省略所有后端请求的主机名。通过这种方式,所有后端请求(在此示例中,所有以/api/ 开头的请求)都将首先由 Angular 开发服务器接收,然后将它们代理到后端。

此处记录了更多配置选项:https://angular.io/guide/build#proxying-to-a-backend-server

请注意,这并不意味着用于您的高效构建!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-01-14
    • 1970-01-01
    • 2019-11-30
    • 2019-10-01
    • 2021-01-07
    • 1970-01-01
    • 1970-01-01
    • 2022-08-03
    相关资源
    最近更新 更多