This commit is contained in:
aaron 2026-05-12 11:19:16 +08:00
parent 40fd0c2282
commit 4397369e35
4 changed files with 81 additions and 11 deletions

View File

@ -7,7 +7,7 @@ services:
environment:
DATABASE_URL: sqlite+aiosqlite:////app/data/palm_reading.db
UPLOAD_DIR: /app/storage/uploads
CORS_ORIGINS: '["http://127.0.0.1:3011","http://localhost:3011"]'
CORS_ORIGINS: '["https://m.xclaw.ren","http://127.0.0.1:3011","http://localhost:3011"]'
ports:
- "8066:8000"
volumes:

0
palm_reading.db Normal file
View File

View File

@ -0,0 +1,80 @@
import { NextRequest } from "next/server";
export const runtime = "nodejs";
export const dynamic = "force-dynamic";
const HOP_BY_HOP_HEADERS = new Set([
"connection",
"keep-alive",
"proxy-authenticate",
"proxy-authorization",
"te",
"trailer",
"transfer-encoding",
"upgrade",
"host",
]);
type RouteContext = {
params: Promise<{ path: string[] }>;
};
function getApiInternalUrl() {
return (process.env.API_INTERNAL_URL || "http://127.0.0.1:8000").replace(/\/$/, "");
}
function buildHeaders(request: NextRequest) {
const headers = new Headers();
request.headers.forEach((value, key) => {
if (!HOP_BY_HOP_HEADERS.has(key.toLowerCase())) {
headers.set(key, value);
}
});
return headers;
}
async function proxy(request: NextRequest, context: RouteContext) {
const { path } = await context.params;
const apiPath = path.join("/");
const targetUrl = new URL(`/api/${apiPath}${request.nextUrl.search}`, getApiInternalUrl());
const method = request.method.toUpperCase();
const hasBody = !["GET", "HEAD"].includes(method);
try {
const upstream = await fetch(targetUrl, {
method,
headers: buildHeaders(request),
body: hasBody ? await request.arrayBuffer() : undefined,
cache: "no-store",
});
const responseHeaders = new Headers(upstream.headers);
responseHeaders.delete("content-encoding");
responseHeaders.delete("content-length");
return new Response(upstream.body, {
status: upstream.status,
statusText: upstream.statusText,
headers: responseHeaders,
});
} catch (error) {
console.error("API proxy failed", {
target: targetUrl.toString(),
error: error instanceof Error ? error.message : String(error),
});
return Response.json(
{
detail: "后端服务暂时不可用,请检查 API_INTERNAL_URL 或后端容器状态。",
target: targetUrl.origin,
},
{ status: 502 },
);
}
}
export const GET = proxy;
export const POST = proxy;
export const PUT = proxy;
export const PATCH = proxy;
export const DELETE = proxy;

View File

@ -2,16 +2,6 @@ import type { NextConfig } from "next";
const nextConfig: NextConfig = {
reactStrictMode: true,
async rewrites() {
const apiInternalUrl = process.env.API_INTERNAL_URL || "http://127.0.0.1:8000";
return [
{
source: "/api/:path*",
destination: `${apiInternalUrl}/api/:path*`,
},
];
},
};
export default nextConfig;