1
This commit is contained in:
parent
40fd0c2282
commit
4397369e35
@ -7,7 +7,7 @@ services:
|
|||||||
environment:
|
environment:
|
||||||
DATABASE_URL: sqlite+aiosqlite:////app/data/palm_reading.db
|
DATABASE_URL: sqlite+aiosqlite:////app/data/palm_reading.db
|
||||||
UPLOAD_DIR: /app/storage/uploads
|
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:
|
ports:
|
||||||
- "8066:8000"
|
- "8066:8000"
|
||||||
volumes:
|
volumes:
|
||||||
|
|||||||
0
palm_reading.db
Normal file
0
palm_reading.db
Normal file
80
web/app/api/[...path]/route.ts
Normal file
80
web/app/api/[...path]/route.ts
Normal 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;
|
||||||
@ -2,16 +2,6 @@ import type { NextConfig } from "next";
|
|||||||
|
|
||||||
const nextConfig: NextConfig = {
|
const nextConfig: NextConfig = {
|
||||||
reactStrictMode: true,
|
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;
|
export default nextConfig;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user