import http from 'http'; import https from 'https'; import { ProxyInfo } from './proxy.ts'; export const defaultApiProxy = [ { path: '/api/router', target: 'https://kevisual.xiongxiao.me', }, { path: '/v1', target: 'https://kevisual.xiongxiao.me', }, ]; /** * 创建api代理 * @param api * @param paths ['/api/router', '/v1' ] * @returns */ export const createApiProxy = (api: string, paths: string[] = ['/api/router', '/v1', '/resources']) => { const pathList = paths.map((item) => { return { path: item, target: new URL(api).origin, }; }); return pathList; }; export const apiProxy = (req: http.IncomingMessage, res: http.ServerResponse, proxyApi: ProxyInfo) => { const _u = new URL(req.url, `${proxyApi.target}`); console.log('proxyApi', req.url, _u.href); // 设置代理请求的目标 URL 和请求头 let header: any = {}; if (req.headers?.['Authorization'] && !req.headers?.['authorization']) { header.authorization = req.headers['Authorization']; } // 提取req的headers中的非HOST的header const headers = Object.keys(req.headers).filter((item) => item && item.toLowerCase() !== 'host'); headers.forEach((item) => { if (item.toLowerCase() === 'origin') { header.origin = new URL(proxyApi.target).origin; return; } if (item.toLowerCase() === 'referer') { header.referer = new URL(req.url, proxyApi.target).href; return; } header[item] = req.headers[item]; }); const options = { host: _u.hostname, path: req.url, method: req.method, headers: { ...header, }, }; console.log('options', JSON.stringify(options, null, 2)); if (_u.port) { // @ts-ignore options.port = _u.port; } const httpProxy = _u.protocol === 'https:' ? https : http; // 创建代理请求 const proxyReq = httpProxy.request(options, (proxyRes) => { // 将代理服务器的响应头和状态码返回给客户端 res.writeHead(proxyRes.statusCode, proxyRes.headers); // 将代理响应流写入客户端响应 proxyRes.pipe(res, { end: true }); }); // 处理代理请求的错误事件 proxyReq.on('error', (err) => { console.error(`Proxy request error: ${err.message}`); res.writeHead(500, { 'Content-Type': 'text/plain' }); res.write(`Proxy request error: ${err.message}`); }); // 处理 POST 请求的请求体(传递数据到目标服务器),end:true 表示当请求体结束时,关闭请求 req.pipe(proxyReq, { end: true }); return; };