import express from 'express' import { getPort } from './configs/config.js' import router from './routes/routes.js' const app = express(); app.use(express.json({ limit: '50mb' })); app.use(express.urlencoded({ extended: true, limit: '50mb' })); // 生成请求ID (UUID格式) function generateRequestId() { return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) { const r = Math.random() * 16 | 0 const v = c === 'x' ? r : (r & 0x3 | 0x8) return v.toString(16) }) } // 获取客户端IP function getClientIp(req) { return req.headers['x-forwarded-for']?.split(',')[0].trim() || req.headers['x-real-ip'] || req.connection?.remoteAddress || req.socket?.remoteAddress || 'unknown' } // 请求日志中间件 app.use((req, res, next) => { const startTime = Date.now() const requestId = generateRequestId() const clientIp = getClientIp(req) // 将请求ID附加到req对象 req.requestId = requestId // 请求开始时打印日志 console.log(`[INFO] [${requestId}] [${clientIp}] ${req.method} ${req.path}`) // 保存原始的 res.json 和 res.end 方法 const originalJson = res.json.bind(res) const originalEnd = res.end.bind(res) // 重写 res.json 方法以捕获响应状态 res.json = function(data) { logRequestEnd(req, res, startTime, requestId, clientIp) return originalJson(data) } // 重写 res.end 方法以捕获流式响应状态 res.end = function(...args) { logRequestEnd(req, res, startTime, requestId, clientIp) return originalEnd(...args) } next() }) // 请求结束日志记录函数 function logRequestEnd(req, res, startTime, requestId, clientIp) { // 避免重复记录 if (res._logged) return res._logged = true const duration = ((Date.now() - startTime) / 1000).toFixed(3) const status = res.statusCode console.log(`[INFO] [${requestId}] [${clientIp}] 响应状态: ${status}`) console.log(`[INFO] [${requestId}] [${clientIp}] 处理时间: ${duration}s`) } app.use((req, res, next) => { res.header('Access-Control-Allow-Origin', '*'); res.header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS'); res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization, X-API-Key, anthropic-version'); if (req.method === 'OPTIONS') { return res.sendStatus(200); } next(); }); app.use(router); app.get('/', (req, res) => { res.redirect('https://www.bilibili.com/video/BV1SMH5zfEwe/?spm_id_from=333.1007.tianma.1-1-1.click&vd_source=1f3b8eb28230105c578a443fa6481550') }) // 错误处理中间件 app.use((err, req, res, next) => { console.error('未处理的错误:', err); res.status(500).json({ error: '内部服务器错误', message: err.message }); }); (async () => { try { const PORT = getPort() app.listen(PORT) .on('listening', () => { console.log(`服务器运行在 http://localhost:${PORT}`) }) .on('error', (err) => { if (err.code === 'EADDRINUSE') { console.error(`\n${'='.repeat(80)}`); console.error(`错误: 端口 ${PORT} 已被占用!`); console.error(''); console.error('请选择以下选项之一:'); console.error(` 1. 停止使用端口 ${PORT} 的进程:`); console.error(` lsof -ti:${PORT} | xargs kill`); console.error(''); console.error(' 2. 使用环境变量更改端口:'); console.error(' export PORT=8080'); console.error(`${'='.repeat(80)}\n`); process.exit(1); } else { console.error('启动服务器失败:', err); process.exit(1); } }); } catch (error) { console.error('启动服务器失败:', error); process.exit(1); } })();