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


当前回答

如果你不想安装依赖,并且正在运行*nix系统,你可以这样做:

hostname -I

你会得到主机的所有地址,你可以在node中使用这个字符串:

const exec = require('child_process').exec;
let cmd = "hostname -I";
exec(cmd, function(error, stdout, stderr)
{
  console.log(stdout + error + stderr);
});

是一行代码,你不需要像'os'或'node-ip'这样可能会意外增加代码复杂性的其他库。

hostname -h

也是你的朋友;-)

希望能有所帮助!

其他回答

对于Linux和macOS,如果你想通过同步方式获取你的IP地址,试试这个:

var ips = require('child_process').execSync("ifconfig | grep inet | grep -v inet6 | awk '{gsub(/addr:/,\"\");print $2}'").toString().trim().split("\n");
console.log(ips);

结果会是这样的:

['192.168.3.2', '192.168.2.1']

使用内部ip:

const internalIp = require("internal-ip")

console.log(internalIp.v4.sync())

这是对已接受答案的修改,它不考虑vEthernet IP地址,如Docker等。

/**
 * Get local IP address, while ignoring vEthernet IP addresses (like from Docker, etc.)
 */
let localIP;
var os = require('os');
var ifaces = os.networkInterfaces();
Object.keys(ifaces).forEach(function (ifname) {
   var alias = 0;

   ifaces[ifname].forEach(function (iface) {
      if ('IPv4' !== iface.family || iface.internal !== false) {
         // Skip over internal (i.e. 127.0.0.1) and non-IPv4 addresses
         return;
      }

      if(ifname === 'Ethernet') {
         if (alias >= 1) {
            // This single interface has multiple IPv4 addresses
            // console.log(ifname + ':' + alias, iface.address);
         } else {
            // This interface has only one IPv4 address
            // console.log(ifname, iface.address);
         }
         ++alias;
         localIP = iface.address;
      }
   });
});
console.log(localIP);

这将返回一个类似192.168.2.169的IP地址,而不是10.55.1.1。

下面是一个简单的JavaScript版本,用于获取单个IP地址:

function getServerIp() {

  var os = require('os');
  var ifaces = os.networkInterfaces();
  var values = Object.keys(ifaces).map(function(name) {
    return ifaces[name];
  });
  values = [].concat.apply([], values).filter(function(val){
    return val.family == 'IPv4' && val.internal == false;
  });

  return values.length ? values[0].address : '0.0.0.0';
}

下面是一段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);