javascript 中用 set 实现黑名单 ip 拦截,核心是利用其 o(1) 平均时间复杂度的 has() 方法快速判断;需统一标准化 ip 字符串格式(如 trim 和 ipv6 规范化),支持动态增删、真实 ip 提取(优先 x-forwarded-for),但不支持 cidr 网段匹配。

用 JavaScript 的 Set 实现黑名单 IP 拦截,核心在于利用其 O(1) 平均时间复杂度的 has() 查找能力——只要把黑名单 IP 字符串存进 Set,每次请求来时调用 set.has(ip) 判断即可,简单高效。
如何构建和维护 IP 黑名单 Set
初始化时将已知黑名单 IP 加入 Set,支持字符串直接添加(IPv4、IPv6 均可,但需保证格式统一):
- 确保所有 IP 存储为标准字符串,例如
"192.168.1.1"或"2001:db8::1";避免前后空格,建议插入前用.trim() - 可从配置文件、数据库或 API 动态加载:
const blockedIPs = new Set(['192.168.1.100', '203.0.113.5'].map(ip => ip.trim()));
- 运行时增删便捷:
blockedIPs.add('192.168.1.101')或blockedIPs.delete('192.168.1.100')
在请求处理中做实时拦截
Node.js(如 Express)中可在中间件里快速校验客户端 IP:
- 注意获取真实 IP:若服务部署在 Nginx 或 CDN 后,应从
X-Forwarded-For或X-Real-IP头读取,而非req.ip(可能被伪造) - 简单拦截逻辑示例:
app.use((req, res, next) => { const clientIP = req.headers['x-forwarded-for']?.split(',')[0].trim() || req.ip; if (blockedIPs.has(clientIP)) { return res.status(403).send('Forbidden: IP blocked'); } next(); });
注意事项与增强建议
单纯用 Set 能满足大多数场景,但实际使用需留意边界情况:
-
IP 格式一致性最关键:IPv6 带缩写(如
::1)或大小写混用会导致匹配失败,建议入库/插入前标准化(如用normalizeIPv6()工具函数) - 不支持 CIDR 网段匹配(如
192.168.1.0/24),如需网段拦截,需配合额外库(如ip-range-check)或改用 Trie 结构 - 内存限制:千万级 IP 仍可接受,但超大规模建议迁移到 Redis 的
SET或布隆过滤器 + 后端持久化 - 热更新:可通过监听配置变更事件或定时拉取,调用
clear()后重新add,避免全量重建影响性能
Set 是轻量、零依赖、开箱即用的黑名单方案,适合中小流量应用或开发/测试环境。上线前记得压测验证单次 has() 耗时是否稳定在微秒级。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











