web:OAuth 回调成功后整页跳转,修 Safari 登录后资源加载卡死 ~2min

现象:Safari/PWA 从 Casdoor 回跳登录后,setup.js(路由 chunk)与用户头像约 2 分钟拿不到连接(连接号显示「-」),手动刷新即恢复;Chrome 正常。排查确认非 h3、非 service worker、非 SSE(/setup 时 startHub 被 !selfDeviceName 守卫拦下),服务端 curl 秒回。

根因:oauth.callback 登录成功后做的是路由软导航 navigate({to:"/"}),复用了 OAuth 流程遗留的 HTTP 连接,这些连接在 Safari 下会卡死后续同源/跨源资源请求约 2 分钟。整页重载能拿到全新连接(印证:手动刷新即好),故改 navigate 为 window.location.replace("/")。auth 已在 sessionStorage,同标签刷新存活;replace 不入历史,避免后退重触已消费的 code。

顺带移除因此 unused 的 useNavigate import。
This commit is contained in:
2026-06-16 00:19:13 +08:00
parent af754dc31f
commit 8f550adbb1
+7 -3
View File
@@ -1,5 +1,5 @@
import { Loader } from "@mantine/core";
import { createFileRoute, useNavigate } from "@tanstack/react-router";
import { createFileRoute } from "@tanstack/react-router";
import { AlertTriangle } from "lucide-react";
import { useEffect, useRef, useState } from "react";
import { completeOAuthLogin } from "../features/auth/auth";
@@ -23,7 +23,6 @@ export const Route = createFileRoute("/oauth/callback")({
function CallbackPage()
{
const search = Route.useSearch();
const navigate = useNavigate();
const [ err, setErr ] = useState<string | null>(null);
// ref guardcompleteOAuthLogin 内部会消费 localStorage 中的 PKCE_VERIFIER /
@@ -70,7 +69,12 @@ function CallbackPage()
return;
}
completeOAuthLogin(search.code, search.state).then(
() => { if (!cancelled) { navigate({ to: "/" }); } },
// 整页跳转(window.location.replace),不是路由软导航。Safari 下,从
// Casdoor 回跳后那条客户端导航会复用 OAuth 流程遗留的 HTTP 连接,而这些
// 连接在 Safari 里会卡死后续资源(setup.js / 头像)约 2 分钟——手动刷新即
// 恢复,印证是连接状态问题。整页重载拿到全新连接,绕开该 bug;auth 已在
// sessionStorage,同标签刷新存活。replace 不入历史,避免后退重触已消费的 code。
() => { if (!cancelled) { window.location.replace("/"); } },
(e) => { showErrDeferred(e instanceof Error ? e.message : String(e)); },
);