Files
infinite-canvas/web/src/app/api/[...path]/route.ts
T
HouYunFei 499439d66b fix(handler): 统一错误处理并替换Next.js重写为路由处理器
- 将所有handler中的Fail函数调用替换为FailError以统一错误处理
- 添加FailError函数实现统一的错误日志记录和响应格式
- 移除Next.js配置中的rewrites并实现统一的API路由代理处理器
- 新增路由处理器支持长连接和大文件上传场景的代理转发
- 更新错误处理逻辑避免将内部错误详情暴露给前端用户
2026-05-22 14:15:45 +08:00

58 lines
1.8 KiB
TypeScript

import type { NextRequest } from "next/server";
export const runtime = "nodejs";
export const maxDuration = 300;
type RouteContext = {
params: Promise<{ path: string[] }>;
};
function proxyHeaders(request: NextRequest) {
const headers = new Headers(request.headers);
headers.delete("host");
headers.delete("content-length");
headers.delete("connection");
return headers;
}
function responseHeaders(response: Response) {
const headers = new Headers(response.headers);
headers.delete("content-length");
headers.delete("content-encoding");
headers.delete("transfer-encoding");
return headers;
}
async function proxy(request: NextRequest, context: RouteContext) {
const { path } = await context.params;
const apiBaseUrl = process.env.API_BASE_URL || "http://127.0.0.1:8080";
const target = `${apiBaseUrl.replace(/\/$/, "")}/api/${path.map(encodeURIComponent).join("/")}${request.nextUrl.search}`;
const hasBody = request.method !== "GET" && request.method !== "HEAD";
try {
const response = await fetch(target, {
method: request.method,
headers: proxyHeaders(request),
body: hasBody ? request.body : undefined,
duplex: hasBody ? "half" : undefined,
} as RequestInit & { duplex?: "half" });
return new Response(response.body, {
status: response.status,
statusText: response.statusText,
headers: responseHeaders(response),
});
} catch (error) {
console.error("Failed to proxy", target, error);
return Response.json({ code: 1, data: null, msg: "接口连接失败,请确认后端服务已启动" }, { status: 502 });
}
}
export const GET = proxy;
export const HEAD = proxy;
export const POST = proxy;
export const PUT = proxy;
export const PATCH = proxy;
export const DELETE = proxy;
export const OPTIONS = proxy;