59 lines
1.9 KiB
TypeScript
59 lines
1.9 KiB
TypeScript
import { NextResponse } from 'next/server';
|
|
|
|
const ANALYTICS_BACKEND = process.env.ANALYTICS_BACKEND_URL || 'http://127.0.0.1:8000';
|
|
|
|
export const dynamic = 'force-dynamic';
|
|
|
|
type RouteContext = {
|
|
params: Promise<{ path: string[] }>;
|
|
};
|
|
|
|
function buildBackendUrl(request: Request, path: string[]): string | null {
|
|
if (!path.length || path.some((segment) => !segment || segment.includes('..'))) {
|
|
return null;
|
|
}
|
|
const source = new URL(request.url);
|
|
const target = new URL(`/analytics/${path.map(encodeURIComponent).join('/')}`, ANALYTICS_BACKEND);
|
|
target.search = source.search;
|
|
return target.toString();
|
|
}
|
|
|
|
async function proxyAnalytics(request: Request, context: RouteContext, method: 'GET' | 'POST') {
|
|
const { path } = await context.params;
|
|
const backendUrl = buildBackendUrl(request, path);
|
|
if (!backendUrl) {
|
|
return NextResponse.json({ message: '分析 API 路徑不合法' }, { status: 400 });
|
|
}
|
|
|
|
try {
|
|
const response = await fetch(backendUrl, {
|
|
method,
|
|
cache: 'no-store',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
},
|
|
body: method === 'POST' ? await request.text() : undefined,
|
|
});
|
|
|
|
const contentType = response.headers.get('content-type') || '';
|
|
if (contentType.includes('application/json')) {
|
|
const data = await response.json();
|
|
return NextResponse.json(data, { status: response.status });
|
|
}
|
|
|
|
const text = await response.text();
|
|
return NextResponse.json({ message: text || '分析服務暫時無法回應' }, { status: response.status });
|
|
} catch (error) {
|
|
const message = error instanceof Error ? error.message : '分析服務暫時無法連線';
|
|
return NextResponse.json({ message }, { status: 502 });
|
|
}
|
|
}
|
|
|
|
export async function GET(request: Request, context: RouteContext) {
|
|
return proxyAnalytics(request, context, 'GET');
|
|
}
|
|
|
|
export async function POST(request: Request, context: RouteContext) {
|
|
return proxyAnalytics(request, context, 'POST');
|
|
}
|