我有一个简单的Node.js程序在我的机器上运行,我想获得我的程序正在运行的PC的本地IP地址。我如何在Node.js中获得它?


当前回答

安装一个名为ip的模块,如下:

npm install ip

然后使用下面的代码:

var ip = require("ip");
console.log(ip.address());

其他回答

根据注释,以下是当前版本Node.js的工作原理:

var os = require('os');
var _ = require('lodash');

var ip = _.chain(os.networkInterfaces())
  .values()
  .flatten()
  .filter(function(val) {
    return (val.family == 'IPv4' && val.internal == false)
  })
  .pluck('address')
  .first()
  .value();

上面一个答案的注释缺少对values()的调用。看起来os.networkInterfaces()现在返回一个对象而不是数组。

很多时候,我发现有多个内部和外部面向接口可用(例如:10.0.75.1,172.100.0.1,192.168.2.3),而我真正想要的是外部接口(172.100.0.1)。

如果其他人也有类似的担忧,这里还有一个关于这个问题的看法,希望能有所帮助……

const address = Object.keys(os.networkInterfaces())
    // flatten interfaces to an array
    .reduce((a, key) => [
        ...a,
        ...os.networkInterfaces()[key]
    ], [])
    // non-internal ipv4 addresses only
    .filter(iface => iface.family === 'IPv4' && !iface.internal)
    // project ipv4 address as a 32-bit number (n)
    .map(iface => ({...iface, n: (d => ((((((+d[0])*256)+(+d[1]))*256)+(+d[2]))*256)+(+d[3]))(iface.address.split('.'))}))
    // set a hi-bit on (n) for reserved addresses so they will sort to the bottom
    .map(iface => iface.address.startsWith('10.') || iface.address.startsWith('192.') ? {...iface, n: Math.pow(2,32) + iface.n} : iface)
    // sort ascending on (n)
    .sort((a, b) => a.n - b.n)
    [0]||{}.address;

下面是一段Node.js代码,它将解析ifconfig的输出并(异步地)返回找到的第一个IP地址:

(它只在Mac OS X v10.6 (Snow Leopard)上测试;我希望它也能在Linux上运行。)

var getNetworkIP = (function () {
    var ignoreRE = /^(127\.0\.0\.1|::1|fe80(:1)?::1(%.*)?)$/i;

    var exec = require('child_process').exec;
    var cached;
    var command;
    var filterRE;

    switch (process.platform) {
        // TODO: implement for OSes without the ifconfig command
        case 'darwin':
             command = 'ifconfig';
             filterRE = /\binet\s+([^\s]+)/g;
             // filterRE = /\binet6\s+([^\s]+)/g; // IPv6
             break;
        default:
             command = 'ifconfig';
             filterRE = /\binet\b[^:]+:\s*([^\s]+)/g;
             // filterRE = /\binet6[^:]+:\s*([^\s]+)/g; // IPv6
             break;
    }

    return function (callback, bypassCache) {
        // Get cached value
        if (cached && !bypassCache) {
            callback(null, cached);
            return;
        }

        // System call
        exec(command, function (error, stdout, sterr) {
            var ips = [];
            // Extract IP addresses
            var matches = stdout.match(filterRE);

            // JavaScript doesn't have any lookbehind regular expressions, so we need a trick
            for (var i = 0; i < matches.length; i++) {
                ips.push(matches[i].replace(filterRE, '$1'));
            }

            // Filter BS
            for (var i = 0, l = ips.length; i < l; i++) {
                if (!ignoreRE.test(ips[i])) {
                    //if (!error) {
                        cached = ips[i];
                    //}
                    callback(error, ips[i]);
                    return;
                }
            }
            // Nothing found
            callback(error, null);
        });
    };
})();

使用的例子:

getNetworkIP(function (error, ip) {
    console.log(ip);
    if (error) {
        console.log('error:', error);
    }
}, false);

如果第二个参数为true,函数将每次执行一次系统调用;否则使用缓存的值。


更新版本

返回所有本地网络地址的数组。

在Ubuntu 11.04 (Natty Narwhal)和Windows XP 32上测试

var getNetworkIPs = (function () {
    var ignoreRE = /^(127\.0\.0\.1|::1|fe80(:1)?::1(%.*)?)$/i;

    var exec = require('child_process').exec;
    var cached;
    var command;
    var filterRE;

    switch (process.platform) {
        case 'win32':
        //case 'win64': // TODO: test
            command = 'ipconfig';
            filterRE = /\bIPv[46][^:\r\n]+:\s*([^\s]+)/g;
            break;
        case 'darwin':
            command = 'ifconfig';
            filterRE = /\binet\s+([^\s]+)/g;
            // filterRE = /\binet6\s+([^\s]+)/g; // IPv6
            break;
        default:
            command = 'ifconfig';
            filterRE = /\binet\b[^:]+:\s*([^\s]+)/g;
            // filterRE = /\binet6[^:]+:\s*([^\s]+)/g; // IPv6
            break;
    }

    return function (callback, bypassCache) {
        if (cached && !bypassCache) {
            callback(null, cached);
            return;
        }

        // System call
        exec(command, function (error, stdout, sterr) {
            cached = [];
            var ip;
            var matches = stdout.match(filterRE) || [];
            //if (!error) {
            for (var i = 0; i < matches.length; i++) {
                ip = matches[i].replace(filterRE, '$1')
                if (!ignoreRE.test(ip)) {
                    cached.push(ip);
                }
            }
            //}
            callback(error, cached);
        });
    };
})();

使用举例:升级版本

getNetworkIPs(function (error, ip) {
console.log(ip);
if (error) {
    console.log('error:', error);
}
}, false);

下面是我获取本地IP地址的实用方法,假设您正在寻找一个IPv4地址,而机器只有一个真实的网络接口。可以很容易地对其进行重构,以返回多接口机器的IP地址数组。

function getIPAddress() {
  var interfaces = require('os').networkInterfaces();
  for (var devName in interfaces) {
    var iface = interfaces[devName];

    for (var i = 0; i < iface.length; i++) {
      var alias = iface[i];
      if (alias.family === 'IPv4' && alias.address !== '127.0.0.1' && !alias.internal)
        return alias.address;
    }
  }
  return '0.0.0.0';
}

谷歌在搜索“Node.js获取服务器IP”时引导我到这个问题,所以让我们为那些试图在他们的Node.js服务器程序中实现这一点的人提供一个替代答案(可能是原始海报的情况)。

在最简单的情况下,服务器只绑定到一个IP地址,应该不需要确定IP地址,因为我们已经知道将它绑定到哪个地址(例如,传递给listen()函数的第二个参数)。

在不太简单的情况下,服务器绑定到多个IP地址,我们可能需要确定客户端连接到的接口的IP地址。正如Tor Valamo所简单建议的,现在,我们可以很容易地从连接的套接字及其localAddress属性中获得这些信息。

例如,如果程序是web服务器:

var http = require("http")

http.createServer(function (req, res) {
    console.log(req.socket.localAddress)
    res.end(req.socket.localAddress)
}).listen(8000)

如果它是一个通用TCP服务器:

var net = require("net")

net.createServer(function (socket) {
    console.log(socket.localAddress)
    socket.end(socket.localAddress)
}).listen(8000)

在运行服务器程序时,该解决方案提供了非常高的可移植性、准确性和效率。

详情请参见:

http://nodejs.org/api/net.html http://nodejs.org/api/http.html