fix: 修复 fetch 拦截器正确处理 JSON 请求体

- 正确处理不同类型的 headers(Headers 对象、数组、普通对象)
- 自动序列化对象类型的请求体为 JSON 字符串
- 确保非 GET/HEAD 请求设置正确的 Content-Type
- 修复登录请求体变成 [object Object] 的问题

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
imeepos 2026-01-13 16:02:28 +08:00
parent c2c097efb3
commit ee119d472f
1 changed files with 34 additions and 8 deletions

View File

@ -37,17 +37,43 @@ export const createFetchWithLogger = (options: FetchLoggerOptions = {}) => {
// 使用统一的 Token 存储键 // 使用统一的 Token 存储键
const token = await storage.getItem(TOKEN_KEY) const token = await storage.getItem(TOKEN_KEY)
if (token) { // 确保 headers 是一个对象
init = { const headers: Record<string, string> = {}
...init, if (init?.headers) {
headers: { if (init.headers instanceof Headers) {
...init?.headers, init.headers.forEach((value, key) => {
authorization: `Bearer ${token}`, headers[key] = value
}, })
} else if (Array.isArray(init.headers)) {
init.headers.forEach(([key, value]) => {
headers[key] = value as string
})
} else {
Object.assign(headers, init.headers)
} }
} }
const response = await originalFetch(input, init) // 添加 Bearer Token
if (token) {
headers['authorization'] = `Bearer ${token}`
}
// 确保 Content-Type 正确设置
if (method !== 'GET' && method !== 'HEAD' && !headers['Content-Type']) {
headers['Content-Type'] = 'application/json'
}
// 序列化请求体(如果是对象)
let body = init?.body
if (body && typeof body === 'object' && !(body instanceof FormData) && !(body instanceof URLSearchParams)) {
body = JSON.stringify(body)
}
const response = await originalFetch(input, {
...init,
headers,
...(body !== undefined && { body }),
})
// 401 未授权处理 // 401 未授权处理
if (response.status === 401 && !isRedirecting) { if (response.status === 401 && !isRedirecting) {