如何在Node.js中获取本地IP地址?

66

我指的不是

127.0.0.1

而是其他计算机用来访问该设备的IP地址,例如:

192.168.1.6


https://dev59.com/nHA65IYBdhLWcg3wvxaE#3654601 - lfergon
可能是在node.js中获取本地IP地址的重复问题。 - alessioalex
8个回答

127

http://nodejs.org/api/os.html#os_os_networkinterfaces


var os = require('os');

var interfaces = os.networkInterfaces();
var addresses = [];
for (var k in interfaces) {
    for (var k2 in interfaces[k]) {
        var address = interfaces[k][k2];
        if (address.family === 'IPv4' && !address.internal) {
            addresses.push(address.address);
        }
    }
}

console.log(addresses);

8
对于那些在网上搜索的人来说,这通常被称为网络IP。 - jonathanberi
2
我将这个技巧封装成了一个名为interface-addresses的模块。在这里查看https://github.com/nisaacson/interface-addresses - Noah
2
只是为了理解,为什么会有多个IP地址?当我使用gulp运行时,我得到了:en0vnic0vnic01en0是browsersync显示给我的那一个。 - Andi Giga
你能帮我解决这个问题吗?https://stackoverflow.com/questions/52241799/failed-to-compile-node-modules-macaddress-lib-windows-js-in-angular-5 @seppo0010 - Zhu
嘿,你可能想评论一下这如何过滤掉有效的非内部IPv6地址。不过,对于这个问题的回答非常好,谢谢。 - Llama D'Attore

105

1
这是最短的解决方案。 - Manolo Carrasco Moñino
11
实际上,如果你只需要 IP 地址,使用这个解决方案将比已接受的解决方案多出约 380 行代码,因为你需要包含 node-ip 模块。 - wacko
3
@wacko:那又怎样,这个已经经过测试并提供了简洁的API。由于它在服务器上运行,380行代码在一个库中实际上不值得一提。而且它本身没有任何依赖关系,这很好。 - Blank Chisui
1
这很酷,但在设置了私有网络的vagrant boxes中不起作用。当你真正想要eth1地址时,你会得到eth0地址。 - HeadCode
1
我一直收到回来的IP是127.0.0.1而不是正确的地址? - ALM
你能帮我解决这个问题吗?https://stackoverflow.com/questions/52241799/failed-to-compile-node-modules-macaddress-lib-windows-js-in-angular-5 @Janjuna - Zhu

10

我需要一个紧凑且单文件脚本的版本,希望对他人有用:

var ifs = require('os').networkInterfaces();
var result = Object.keys(ifs)
  .map(x => [x, ifs[x].filter(x => x.family === 'IPv4')[0]])
  .filter(x => x[1])
  .map(x => x[1].address);

或者回答原始问题:

var ifs = require('os').networkInterfaces();
var result = Object.keys(ifs)
  .map(x => ifs[x].filter(x => x.family === 'IPv4' && !x.internal)[0])
  .filter(x => x)[0].address;

那些超长的一行代码让我崩溃了。我更喜欢多行且有缩进的写法。不过这确实是个优美的解决方案。 - The Qodesmith
1
@MarcusParsons:你测试过了吗? - Ebrahim Byagowi
1
我已经删除了我的评论。实际上,.filter(x => x)会删除我没有看到的未定义条目。我确实进行了测试,但是我没有未定义的条目。之后我在一个REPL服务器上进行了测试,并出现了未定义的条目。谢谢,Ebrahim! - Marcus Parsons

10
$ npm install --save quick-local-ip

随后

var myip = require('quick-local-ip');

//getting ip4 network address of local system
myip.getLocalIP4();

//getting ip6 network address of local system
myip.getLocalIP6();

6

https://github.com/dominictarr/my-local-ip

$ npm install -g my-local-ip
$ my-local-ip

或者
$ npm install --save my-local-ip
$ node
> console.log(require('my-local-ip')())

一个非常小的模块,只做这个。

1

野蛮的一行代码即将到来

基于被接受的答案,这个代码将会构建一个对象数组,其中包含根据地址属性条件而有所不同的条目。

[{name: {interface name}, ip: {ip address}}, ...]

const ips = Object.entries(require("os").networkInterfaces()).reduce((acc, iface) => [...acc, ...(iface[1].reduce((acc, address) => acc || (address.family === "IPv4" && !address.internal), false) ? [{name: iface[0], ip: iface[1].filter(address => address.family === "IPv4" && !address.internal).map(address => address.address)[0]}] : [])], []);
console.log(ips);

解释:
const ips = Object.entries(require("os").networkInterfaces()) // fetch network interfaces
.reduce((acc, iface) => [ // reduce to build output object
    ...acc, // accumulator
    ...(
        iface[1].reduce((acc, address) => acc || (address.family === "IPv4" && !address.internal), false) ? // conditional entry
        [ // validate, insert it in output
            { // create {name, ip} object
                name: iface[0], // interface name
                ip: iface[1] // interface IP
                .filter(address => address.family === "IPv4" && !address.internal) // check is IPv4 && not internal
                .map(address => address.address)[0] // get IP
            }
        ] 
        : 
        [] // ignore interface && ip
    )
], []);

输出示例:

Array(4) [Object, Object, Object, Object]
length:4
__proto__:Array(0) [, …]
0:Object {name: "vEthernet (WSL)", ip: "172.31.xxx.x"}
1:Object {name: "Ethernet", ip: "10.0.x.xx"}
2:Object {name: "VMware Network Adapter VMnet1", ip: "192.168.xxx.x"}
3:Object {name: "VMware Network Adapter VMnet8", ip: "192.168.xx.x"}

0

稍作修改 Ebrahim的回答,加入了一些ES6和模块语法,让代码更简洁:

import { networkInterfaces } from "os";
const netInterfaces = networkInterfaces();
const [{ address }] = Object.values(netInterfaces).flatMap((netInterface) =>
  netInterface.filter((prop) => prop.family === "IPv4" && !prop.internal)
);
console.log(address) // -> '192.168...'

0
自从Node版本0.9.6以来,有一种简单的方法可以基于每个请求获取服务器的IP地址。如果您的计算机具有多个IP地址,甚至在本地主机上执行某些操作时,这可能很重要。 req.socket.localAddress将返回基于当前连接的运行节点的机器的地址。
如果您有一个公共IP地址为1.2.3.4,并且有人从外部访问您的节点服务器,则req.socket.localAddress的值将为"1.2.3.4"
如果您从localhost访问同一台服务器,则地址将为"127.0.0.1"
如果您的服务器具有多个公共地址,则req.socket.localAddress的值将是套接字连接的正确地址。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接