仅在第一次加载 Angular 网页时使用 Safari 接收 401 状态

Posted

技术标签:

【中文标题】仅在第一次加载 Angular 网页时使用 Safari 接收 401 状态【英文标题】:Receiving 401 status with Safari while loading a an angular webpage only for the first time 【发布时间】:2019-12-25 04:07:47 【问题描述】:

问题

当使用 Safari 而不是 Chrome 作为浏览器时,当我们加载我们的 Web 应用程序主页时,我们会收到 401 状态,这只会在该选项卡上第一次发生,当我们打开一个新选项卡并重新加载应用程序时加载正常。

我们使用的技术是 MEAN 堆栈,当我们使用 Chrome/Firefox 作为我们的浏览器时一切都很好(没有给出 401 错误并且身份验证似乎很好),但是当我们切换到 Safari 时,它就不起作用了。

我在 SO 上查看了类似的帖子 Receiving 401 status with Safari not Chrome in React 并确保端点有前斜线

API 调用

get_change_lifecycle_data()
    const params = new HttpParams().set('params', this.enteredValue);
    this.http.get('https://change-life-cycle.region02.hoster.company.com/api/change_life_cycle/',params)
        .subscribe(response => 
        console.log("change data:");
         console.log(response);
         this.newPost = response
        //  this.splice_gerrits();
     );

请求失败:

Summary
URL: https://bati.company.com/runtime-es2015.858f8dd898b75fe86926.js
Status: 401 Unauthorized
Source: Network

Request
Origin: https://bati.company.com
Accept: */*
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) companyWebKit/605.1.15 (Khtml, like Gecko) Version/11.1.2 Safari/605.1.15
Referer: https://bati.company.com/

Response
Content-Type: text/html
Date: Tue, 20 Aug 2019 00:02:58 GMT
Connection: keep-alive
Server: companyHttpServer/54b48526
Content-Length: 207
X-B3-TraceId: b39ab56a5e87f4f0
Strict-Transport-Security: max-age=31536000
Www-Authenticate: Basic realm="Enter your company OD credentials"

打开新标签后请求成功:

Summary
URL: https://bati.company.com/runtime-es2015.858f8dd898b75fe86926.js
Status: 200 OK
Source: Memory Cache

Request
No request, served from the memory cache.

Response
ETag: "5d5b0e97-5a0"
Content-Type: application/x-javascript
Date: Tue, 20 Aug 2019 00:01:36 GMT
Last-Modified: Mon, 19 Aug 2019 21:03:19 GMT
Server: companyHttpServer/54b48526
Content-Length: 1440
Connection: keep-alive
Accept-Ranges: bytes
X-B3-TraceId: ecc642668834014e
Strict-Transport-Security: max-age=31536000

更新:--

我能够通过发送 curl 请求来复制问题,但收到 401 错误响应

curl 'https://bati.company.com/runtime-es2015.858f8dd898b75fe86926.js' \
-XGET \
-H 'Origin: https://bait.company.com' \
-H 'Accept: */*' \
-H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) companyWebKit/605.1.15 (KHTML, like Gecko) Version/11.1.2 Safari/605.1.15' \
-H 'Referer: https://bait.company.com/'

401 错误响应

<html>
<head><title>401 Authorization Required</title></head>
<body bgcolor="white">
<center><h1>401 Authorization Required</h1></center>
<hr><center>CompanyHttpServer/54b48526</center>
</body>
</html>

更新 2:

curl -u username:password 'https://bati.company.com/runtime-es2015.858f8dd898b75fe86926.js' -XGET -H 'Origin: https://ibait.apple.com' -H 'Accept: */*' -H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/11.1.2 Safari/605.1.15' -H 'Referer: https://ibait.apple.com/'

更新3:

api_change_foldscore_data()
    const username = 'username'; // need to get these values from X-Forwarded-User
    const password = 'password';
    const headers = new HttpHeaders(
      Authorization: 'Basic ' + btoa(username + ':' + password)
    );
    this.http.get('https://change-life-cycle.hoster.company.com/api/change_fold_score', headers, params)
        .subscribe(response => 
        console.log("change data:");
         console.log(response);
         this.newPost = response
     );

【问题讨论】:

【参考方案1】:

在随后的请求(新选项卡)中,它从内存缓存中提供。所以它似乎在缓存中,不确定它是如何到达那里的。您能否尝试清除 chrome 和 safari 中的所有缓存并刷新以查看您的新 api 调用是否在两个浏览器中都具有所有必需的授权标头?

【讨论】:

我在Safari Private模式下试过,输入用户名和密码总是把我带到一个空白页,我在web inspector看到401 unauthorized,我在Google Incognito根本看不到这个问题或者Mozilla after clearing cache,你指的authorized headers是什么要求? 我更新了问题,如果我将username:password 附加到 curl 请求中,我发现它有效,我如何确保 curl 请求获取通过 angular 附加的用户名和密码? curl 请求与 angular 无关。 chrome 中成功的请求是什么样的?在 safari 中是否也提出了相同的请求?

以上是关于仅在第一次加载 Angular 网页时使用 Safari 接收 401 状态的主要内容,如果未能解决你的问题,请参考以下文章

Foundation 兜风仅在首次加载问题时启动

使用 $http 加载 json 数据时的 Angular-grid

仅在 Angular SPA 中的页面加载之间缓存会话数据

仅在 html 代码中使用 javascript 重新加载特定页面一次

mapGetters 的反应性问题仅在第一次加载时

如何仅在 Angular 的某些页面上显示标题组件(现在它仅在重新加载时显示)