/** * 简单内存速率限制 * 每个 IP 每小时最多允许 MAX_REQUESTS 次提交 */ const WINDOW_MS = 60 * 60 * 1000 // 1 小时 const MAX_REQUESTS = 5 // Map const store = new Map() // 每 2 小时清理一次过期记录,防止内存泄漏 setInterval(() => { const now = Date.now() for (const [ip, record] of store.entries()) { if (now > record.resetAt) { store.delete(ip) } } }, 2 * 60 * 60 * 1000) /** * 检查并记录一次请求 * @param {string} ip * @returns {{ allowed: boolean, remaining: number, resetAt: number }} */ export function checkRateLimit(ip) { const now = Date.now() const record = store.get(ip) if (!record || now > record.resetAt) { store.set(ip, { count: 1, resetAt: now + WINDOW_MS }) return { allowed: true, remaining: MAX_REQUESTS - 1, resetAt: now + WINDOW_MS } } if (record.count >= MAX_REQUESTS) { return { allowed: false, remaining: 0, resetAt: record.resetAt } } record.count++ return { allowed: true, remaining: MAX_REQUESTS - record.count, resetAt: record.resetAt } }