geo/frontend/lib/api/client.ts

57 lines
1.5 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { getSession } from "next-auth/react";
import type { Session } from "next-auth";
export const API_BASE = process.env.NEXT_PUBLIC_API_URL || "http://localhost:8000";
export function getApiUrl(path: string): string {
return `${API_BASE}${path}`;
}
export async function fetchWithAuth(
url: string,
options: RequestInit = {},
token?: string
) {
// 如果没有显式传入 token尝试从 NextAuth session 获取
let authToken = token;
if (!authToken && typeof window !== "undefined") {
try {
const session = await getSession();
authToken = (session as Session)?.accessToken;
} catch {
// ignore session fetch error
}
}
const headers: Record<string, string> = {
"Content-Type": "application/json",
...((options.headers as Record<string, string>) || {}),
};
if (authToken) {
headers["Authorization"] = `Bearer ${authToken}`;
}
const res = await fetch(`${API_BASE}${url}`, { ...options, headers });
if (res.status === 401) {
// 不要自动跳转登录页,让页面组件/layout自行处理认证状态
throw new Error("登录已过期,请重新登录");
}
if (!res.ok) {
let errorDetail = `请求失败 (HTTP ${res.status})`;
try {
const error = await res.json();
errorDetail = error.detail || error.message || errorDetail;
} catch {
// 解析失败,使用默认错误信息
}
throw new Error(errorDetail);
}
if (res.status === 204) {
return null;
}
return res.json();
}