仅在特定条件下被 CORS 策略阻止的 Angular 请求

Posted

技术标签:

【中文标题】仅在特定条件下被 CORS 策略阻止的 Angular 请求【英文标题】:Angular requests blocked by CORS policy only under certain conditions 【发布时间】:2021-04-14 03:32:05 【问题描述】:

您好,我使用本指南创建了一个带有 Spring Boot/Spring Security 后端的 Angular 应用:

https://www.javaguides.net/2019/04/spring-boot-spring-security-angular-example-tutorial.html

在我的 Controller 类中,我有以下简单的请求方法:

    @GetMapping("/test/gameId")
    @CrossOrigin(origins = "http://localhost:4200")
    public ResponseMessage test(@PathVariable int gameId) 
        return new ResponseMessage("HelloMessage", "Hello there id=" + gameId);
    

我在测试路由中添加了一个 .permitAll():

    protected void configure(HttpSecurity http) throws Exception 
        http.csrf()
            .disable()
            .authorizeRequests()
            .antMatchers(HttpMethod.OPTIONS, "/**")
            .permitAll()
            .antMatchers("/api/v1/**")
            .permitAll()
            .antMatchers("/test/**")
            .permitAll()
            .anyRequest()
            .authenticated()
            .and()
            .httpBasic();
    

在我的 Angular 前端,我在主页上有一个简单的方法来测试该方法:

  doSomething() 
    console.log("Doing something...");
    this.http.get("http://localhost:8080/test/75154").subscribe((data) => 
        console.log(data);
    );
  

问题 1:登录和页面刷新时出现 CORS 策略错误

如果我以注销用户身份运行我的页面并单击按钮,我会得到预期的响应:

type: "HelloMessage", message: "Hello there id=75154", data: null

如果我然后登录,返回主页并再次单击按钮,响应仍然有效。 问题是当我刷新页面时 - 我仍然登录,但现在请求被 CORS 策略阻止:

Access to XMLHttpRequest at 'http://localhost:8080/test/75154' from origin 'http://localhost:4200' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
zone-evergreen.js:2845 GET http://localhost:8080/test/75154 net::ERR_FAILED
core.js:4352 ERROR 
HttpErrorResponse headers: HttpHeaders, status: 0, statusText: "Unknown Error", url: "http://localhost:8080/test/75154", ok: false, …
error: ProgressEvent isTrusted: true, lengthComputable: false, loaded: 0, total: 0, type: "error", …
headers: HttpHeaders normalizedNames: Map(0), lazyUpdate: null, headers: Map(0)
message: "Http failure response for http://localhost:8080/test/75154: 0 Unknown Error"
name: "HttpErrorResponse"
ok: false
status: 0
statusText: "Unknown Error"
url: "http://localhost:8080/test/75154"

如果我单击注销并返回主页,我可以再次收到来自后端的请求,而不会出现此错误消息。 POSTMAN 也可以接收请求。

问题 2:保护 /test 也会产生 CORS 错误,而不是未经授权的响应 如果我从配置方法中删除 2 行以允许所有测试路径,我会在 POSTMAN 中得到预期的响应,即该路径现在未经授权:


    "timestamp": "2021-01-08T12:05:54.665+00:00",
    "status": 401,
    "error": "Unauthorized",
    "message": "Unauthorized",
    "path": "/test/5"

但是,在 Angular 应用程序本身中,我收到的是 CORS 策略错误,而不是未经授权的 JSON。我可以登录并获得正确的响应,但我仍然遇到问题 1 的问题,即刷新页面会返回 CORS 策略错误。同样,注销然后重新登录将解决问题,直到页面被刷新。

HttpInterceptor 和 AuthService 类如上面链接中的指南所示。

【问题讨论】:

你能检查一下这个答案***.com/questions/65514482/… 感谢您的链接,这似乎解决了获取 CORS 错误而不是未经授权的响应的问题。 如果对您有帮助,您可以将其标记为已接受的答案或点赞, 我认为我的帐户仍然太普通,无法投票,否则我会! 【参考方案1】:

已下载教程,它开箱即用。

现在解决问题,在登录后执行 Hello World 页面的硬刷新,可以在不添加代码的情况下重新创建问题。

原因是本教程的作者没有在localStorage 中包含用于存储凭据的代码。因此,当页面重新加载时,客户端应用程序会丢失存储在状态中的凭据,并且飞行前请求被拒绝,这反过来又会导致 CORS 错误。

因此,没有错误,只是缺少一些代码以使其按照您的要求工作。

也许会问一个关于如何在 Angular 中将凭据保存到 localStorage 的新问题(我对 Angular 不太擅长)。

【讨论】:

感谢您的回复,我已经添加了这个,但应用程序仍然以相同的方式响应。 当然,虽然我不确定是什么导致了这个问题。刷新后应用程序不应该仍然处于相同状态,为什么当 POSTMAN 收到正确的响应时它会给出 CORS 错误而不是 auth 错误? @whereami:抱歉耽搁了,我不得不在这台电脑上安装 Angular。我发现了你的问题,请查看我的更新答案。 非常感谢您的麻烦。看起来您可以简单地使用 localStorage 而不是具有相同方法名称的 sessionStorage 进行存储。上面的silentsudo链接删除了CORS的问题,我现在得到了预期的身份验证错误,尽管刷新后这仍然是一个问题,因为它不再被授权。我想我可能需要一种持久化令牌的方法。 @whereami:查看了silentsudo 的链接。如果您修复了 localStorage,则不必添加比项目中更多的 CORS 内容。

以上是关于仅在特定条件下被 CORS 策略阻止的 Angular 请求的主要内容,如果未能解决你的问题,请参考以下文章

仅在文件上传中出现 Asp.Net Core API CORS 策略错误

跨域请求仅在 Firefox 中被阻止! [选项:403 禁止]

CORS 仅在 Firefox 和 Safari 上且仅在 onClick() 上阻止内容

AngularJS 的 CORS 错误仅在 FireFox 中发布

Laravel 5:仅在一个 URL 上路由 CORS 问题

仅在涉及文件上载/下载时阻止跨源请求