我目前正在尝试获得所请求的用户的 IP。问题是 IP 返回的是 ::ffff:127.0.0.1而不是 127.0.0.1。我尝试使用 trusted proxy选项(尽管没有使用代理) ,但是 req.ips是空白的。使用4.x Express.js。
::ffff:127.0.0.1
127.0.0.1
trusted proxy
req.ips
router.get('/', function(req, res, next) { console.log('ip', req.ip) res.send({}) });
Windows 7默认启用了 IPv6。尽管我的服务器只监听 IPv4,但是 Windows 7将 ::ffff:前缀发送到 IPv4,作为向 IPv6过渡的一部分
::ffff:
::ffff:0:0:0/96ー无状态 IP/ICMP 转换(SIIT)协议所使用的 IPv4转换地址的前缀。
::ffff:0:0:0/96
从 IPv4过渡
我在比较 ipv4映射地址时遇到了一些问题,发现 Ipad 博士库很有帮助: -)
例句
_.isEqual(ipaddr.process('::ffff:127.0.0.1'), ipaddr.process('127.0.0.1')) === true
::ffff:是放置在 IPv6(128位)空间内的 IPv4(32位)地址的子网前缀。IPv6分为两部分: 子网前缀和接口后缀。每一个都是64位长,或者说,4组4个十六进制字符。
在 IPv6中,你可以移除前导零,然后移除连续的零,这意味着 ::ffff:实际上转换为 0000:0000:ffff:0000,这个地址被指定为 IPv4到 IPv6子网前缀,所以任何 IPv6处理器都会理解它使用的是 IPv4地址,并相应地处理它。
0000:0000:ffff:0000
在不久的将来,IP 地址都将是 IPv6,这是因为我们几乎没有数字(42亿,减去一些空间的杂项。目的)。
IPv6允许更大的空间 对任何人来说都足够了”——比尔 · 盖茨在 IPv6上的讲话。
开始使用 IPv6名称空间寻址 IP 地址很重要,因此在代码中包含 ::ffff:,因为将来这些冒号之间会有真正的十六进制数据。如果出于审美原因将其剥离,则当它切换到 IPv6网络或遇到 IPv6地址时,代码将中断。
一些网络目前正在运行 IPv6,你很快就会遇到 IPv6的 IP 地址; 现在就跨越这一步,否则将来就有可能破坏你的代码。
这个问题的 TL; DR (简称 DR)版本是: 一切正常。不要改变它,它是 IPv4地址的 IPv6版本。
如果你想让你的代码与 IPv6兼容,你所要做的就是检查 ::ffff:前缀... 如果它存在,删除它,并处理其余的 IPv4... 如果 ::ffff:不存在,它是一个 IPv6地址,需要这样处理。 您可以通过查看字符串中是否包含句点来进行双重检查,如果包含,则为 IPv4。
记住除了需要对 IP 地址进行调整之外的所有事情,您只是在记录 IP,对吗?对于解析器和日志聚合来说,期待将来的 ::ffff:127.0.0.1等非常重要。除非你需要更改一个 IP,否则就让它作为你收到的。
这似乎是 ipv6的一个特点: 对于 ipv4地址,ipv6似乎将 ipv6符号和 ipv4符号混合在一起。
为了以简单的、未混合的表示法获得 ipv4和 ipv6地址,我使用:
var ip = req.headers['x-forwarded-for'] || req.connection.remoteAddress; if (ip.substr(0, 7) == "::ffff:") { ip = ip.substr(7) }
您可以使用套接字单独获取 IP 地址,也可以使用指定的家庭获取 IP 地址
var app = require('express')(); app.get("/ip", (req, res) => { console.log(req.ip) let ip = req.ip.split(':'); let ip_details = req.socket.address(); console.log(ip_details); // { address: '::ffff:127.0.0.1', family: 'IPv6', port: 3001 console.log(ip[3]);//127.0.0.1 res.json(ip[3]); }
如果只需要 IPv4,可以强制节点服务器使用 IPv4进行侦听。
对于快捷应用程序编辑 /bin/www:
/bin/www
改变
server.listen(port);
到
server.listen(port, '0.0.0.0');
这至少对我有用。
Https://nodejs.org/api/net.html#net_server_listen_port_host_backlog_callback
var ip = req.ip.split(':').pop();
尝试通过删除子网获取精确的 IP 地址,
let ip = req.headers['x-forwarded-for'] || req.connection.remoteAddress; ip = ip.toString().replace('::ffff:', '');