diff --git a/web/shared/api/client.ts b/web/shared/api/client.ts
index 04d459d..5b73a4d 100644
--- a/web/shared/api/client.ts
+++ b/web/shared/api/client.ts
@@ -40,12 +40,16 @@ async function request(method: string, path: string, body?: unknown, init?: R
const headers: Record = { Accept: 'application/json', ...authHeaders() }
if (body !== undefined) headers['Content-Type'] = method === 'PATCH' ? 'application/merge-patch+json' : 'application/json'
if (method !== 'GET' && csrfToken) headers['X-CSRF-Token'] = csrfToken
+ // 没有时限的 fetch 在被黑洞的线路上会一直挂着,轮询的界面就停在旧数据上;超时后抛错,下一轮轮询换一条连接重试
+ const timeout = AbortSignal.timeout(method === 'GET' ? 15_000 : 30_000)
+ const signal = init?.signal ? AbortSignal.any([init.signal, timeout]) : timeout
const response = await fetch(resolveUrl(path), {
method,
headers,
credentials: isRemote() ? 'omit' : 'include',
body: body === undefined ? undefined : JSON.stringify(body),
...init,
+ signal,
})
if (response.status === 204) return undefined as T
const text = await response.text()