Deno Deploy中request.ip未定义致express-rate-limit报错求助
解决Deno部署Express+express-rate-limit时req.ip未定义的问题
问题根源
Deno Deploy的Node.js兼容层把Express的req.socket替换成了FakeSocket,这个对象不携带真实客户端IP信息;同时兼容层没有把Deno原生请求的IP数据正确映射到Express的req.ip、req.connection.remoteAddress等字段,导致express-rate-limit无法获取IP触发报错。
解决方案
自定义express-rate-limit的keyGenerator函数,直接从Deno原生请求对象里提取真实IP:
修改后的代码示例
"use strict" import express from 'express'; import bodyParser from 'body-parser'; import mongoose from 'mongoose'; import rateLimit from 'express-rate-limit'; const app = express(); mongoose.connect("..."); const db = mongoose.connection; db.on('error', console.error.bind(console, 'connection error:')); db.once('open', function() { console.log('Connected to MongoDB'); }); app.use(bodyParser.json()); // 自定义keyGenerator,从Deno原生请求获取IP const limiter = rateLimit({ windowMs: 1 * 60 * 1000, max: 3, keyGenerator: (req) => { // Deno Deploy环境下,req.raw对应原生Request对象 const rawRequest = req.raw; // 优先用Cloudflare提供的真实客户端IP(Deno Deploy基于Cloudflare部署) if (rawRequest.cf?.connectingIp) { return rawRequest.cf.connectingIp; } // 备用方案:从x-forwarded-for头部取第一个IP(处理多代理场景) const xForwardedFor = rawRequest.headers.get('x-forwarded-for'); if (xForwardedFor) { return xForwardedFor.split(',')[0].trim(); } // 极端情况返回默认值,避免rate-limit触发报错 return 'fallback-ip'; } }); app.post('/api/users', limiter, async (req, res) => { try { const variable = await db.collection("users").findOne({ [req.body.user]: { $exists: true } }) if (!variable) return res.status(404).send('Not found'); res.send(variable); } catch (error) { res.status(500).send('Internal Server Error'); } }); app.listen(5000, () => { console.log(`running`); });
补充说明
- 为什么
app.set('trust proxy', 1)无效?因为该配置是让Express从x-forwarded-for头部解析IP,但Deno Deploy的兼容层没有把原生请求的x-forwarded-for头部正确传递到Express的req.headers里(从你提供的部署日志能看到X-Forwarded-For: undefined),必须直接从Deno原生的req.raw.headers读取。 - Deno Deploy基于Cloudflare架构,
req.raw.cf.connectingIp是最可靠的真实客户端IP来源,无需处理多代理的IP串问题。
内容的提问来源于stack exchange,提问作者Luma
相关产品推荐
相关产品推荐

