项目在进行 JWT 改造后,用户反馈在 Safari 浏览器中出现 Bug,即打开特定页面会自动跳转至登录页面,但打开其他页面则正常。通过对用户操作路径的模拟,成功复现了该问题。经分析,发现是由于接口返回的 301 重定向状态码导致。在重定向过程中,Safari 浏览器没有携带自定义的Authorization 请求头,进而导致接口鉴权失败,返回 401(Unauthorized)状态。这一发现揭示了 Safari 在处理 301 重定向时的特殊行为,即自动发起请求但不携带某些请求头,而 Chrome 浏览器则能正常处理。通过 Charles 和 Proxyman 等工具的辅助,尝试修改响应码以验证不同浏览器的处理逻辑,但最终未能解决 Safari 的问题。
经过多次尝试和搜索,发现并非各浏览器在处理 301 响应码时存在差异,而是 Safari 在重定向时未正确处理某些请求头,导致鉴权失败。为了进一步验证和解决这一问题,作者向 webkit 团队提交了一个 Bug,并提供了复现的代码示例。经过一段时间的等待,官方确认已在新版本中修复了该问题,并提供了测试用的 Demo。作者通过 Koa 处理请求时,发现了 Node.js http 模块在处理 header 字段时将所有 key 转换为小写的问题,这在一定程度上解释了 Safari 的异常行为。为解决这一问题,Node.js 提供了新的 API `req.rawHeaders` 以获取原始数据,使得在处理重定向时能够保持原始请求头的大小写。
文章中还提到了通过将 token 存储在 cookie 中作为解决方案,但这种方法依赖于后端的配合,且可能导致对 JWT 方案的放弃。此外,作者尝试使用 Fetch API 的 `redirect` 属性进行手动处理,但发现其并非预期的“手动处理”而是浏览器的自动处理逻辑。在探索过程中,XMLHttpRequest 作为替代方案被发现能够获取到重定向的 URL,且具备终止重定向请求的能力。最终,作者提出了一种结合 cookie 和 XMLHttpRequest 的 Hack 思路,虽然在 Safari 中可完美运行,但在控制台会打印出 401 错误,但对 JS 运行逻辑无影响。
整个过程中,作者意外地收获了多个新知识,包括不同浏览器在处理 301 重定向时的差异、Node.js http 模块处理 header 字段的方式、以及如何利用现有工具和 API 来解决特定问题。虽然没有采用上述任何一个方案作为最终解决方案,但文章提供了一个全面的分析和探索过程,展示了面对技术难题时的思考和实践方法。
本文如未解决您的问题请添加抖音号:51dongshi(抖音搜索懂视),直接咨询即可。