Files
router-studio/web/src/proxy.ts
abearxiong 8e29fe4545 feat: update routing and API handling, improve query functionality, and enhance UI components
- Changed import path for routes in next-env.d.ts
- Updated dependencies in package.json, including @kevisual/api and @kevisual/query
- Added delete functionality in QueryView component
- Modified run function in studio to accept a custom type
- Enhanced searchRoutes function in studio store with Fuse.js for better filtering
- Updated DataItemForm to use QueryRouterServer from the browser
- Added dynamic URL handling in query module
- Improved proxy request handling based on app key
- Adjusted TypeScript configuration for stricter checks
- Created a new page component for dynamic routing
- Introduced a new Toaster component for notifications
2026-01-21 18:51:03 +08:00

72 lines
2.4 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 { NextRequest, NextResponse } from 'next/server';
const API_URL = process.env.API_URL || 'http://localhost:51515';
console.log(`Proxy API_URL: ${API_URL}`);
/**
* 通用代理函数
* @param request 原始请求
* @param targetHost 目标服务器地址(如 http://localhost:51515
* @returns NextResponse 代理响应
*/
async function proxyRequest(request: NextRequest, targetHost: string): Promise<NextResponse> {
const { pathname } = request.nextUrl;
const targetUrl = new URL(pathname + request.nextUrl.search, targetHost);
try {
console.log(`Proxying request to: ${targetUrl.toString()}`);
const response = await fetch(targetUrl.toString(), {
method: request.method,
headers: {
// 复制原始请求的所有头部
...Object.fromEntries(request.headers.entries()),
// 确保转发 cookie
cookie: request.headers.get('cookie') || '',
},
body: request.method !== 'GET' && request.method !== 'HEAD' ? await request.text() : undefined,
// 包含 cookie 的请求
credentials: 'include',
});
// 创建响应,保留原始响应的所有头部(包括 Set-Cookie
const responseHeaders = new Headers(response.headers);
return new NextResponse(response.body, {
status: response.status,
statusText: response.statusText,
headers: responseHeaders,
});
} catch (error) {
console.error('Proxy error:', error);
return NextResponse.json(
{ error: 'Proxy request failed' },
{ status: 502 }
);
}
}
export async function proxy(request: NextRequest) {
const { pathname } = request.nextUrl;
const method = request.method;
const [username, appKey] = pathname.split('/').filter(Boolean);
const searchParams = request.nextUrl.searchParams;
const path = searchParams.get('path') || '';
// 代理 /api 请求
if (pathname.startsWith('/api')) {
return proxyRequest(request, API_URL);
}
// 代理 /root/home 或 /root/home/ 请求 (第二个路径段后可以为空或以 / 结尾)
if (pathname.startsWith('/root') && appKey !== 'v1') {
return proxyRequest(request, API_URL);
}
if (pathname.startsWith('/root') && path && appKey === 'v1') {
return proxyRequest(request, API_URL);
}
return NextResponse.next();
}
export const config = {
matcher: ['/api/:path*', '/root/:segment/:path*'],
};
export default proxy;