获取node.js中的本地IP地址

yoj*_*o87 291 javascript ip node.js

我有一个简单的node.js程序在我的机器上运行,我想获得运行我程序的PC的本地IP地址.我如何使用node.js获取它?

小智 389

'use strict';

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 (alias >= 1) {
      // this single interface has multiple ipv4 addresses
      console.log(ifname + ':' + alias, iface.address);
    } else {
      // this interface has only one ipv4 adress
      console.log(ifname, iface.address);
    }
    ++alias;
  });
});

// en0 192.168.1.101
// eth0 10.0.0.101
Run Code Online (Sandbox Code Playgroud)

  • 可以使用一些评论. (70认同)
  • var _ = require('underscore'); var ip = _.chain(require('os').networkInterfaces()).flatten().filter(function(val){return(val.family =='IPv4'&& val.internal == false)}) .pluck( '地址')第一()值().; 执行console.log(IP) (15认同)
  • **node >= 7.0.0** 没有 lodash 的单线:`Object.values(require('os').networkInterfaces()).reduce((r, list) => r.concat(list.reduce) ((rr, i) => rr.concat(i.family==='IPv4' && !i.internal && i.address || []), [])), [])` (15认同)
  • 猜猜内循环中缺少一个"alias ++" (8认同)
  • “下划线”“低破折号”“一行”- 粗俗。 (8认同)
  • 如果我只想检索活动接口的 IP 地址怎么办? (4认同)
  • @CarterCole 您需要在展平之前额外调用 .values() 。 (3认同)
  • 更简单的单行代码,没有减少(当没有找到时返回未定义) `[].concat(...Object.values(require('os').networkInterfaces())).find(x => !x.internal && x.family === 'IPv4')?.address` (2认同)

Xed*_*mal 220

到目前为止,os.networkInterfaces在Windows上不起作用.运行程序来解析结果似乎有点不确定.这是我使用的.

require('dns').lookup(require('os').hostname(), function (err, add, fam) {
  console.log('addr: '+add);
})
Run Code Online (Sandbox Code Playgroud)

这应该返回您的第一个网络接口本地IP.

  • `os.networkInterfaces()`现在适用于Windows. (14认同)
  • 使用DNS查找并不总是一个好主意,因为它可以返回错误信息(即缓存数据).在我看来,使用'os.networkInterfaces'是一个更好的主意. (7认同)
  • 如果您的服务器在某处有 dns 条目,则可以使用 DNS。然而,在很多应用程序中没有 dns 条目(例如我的笔记本电脑)。os.networkInterfaces() 可能是要走的路。 (5认同)
  • @HermannIngjaldsson:这不是一个非常全面的批评.你可以再详细一点吗?也许拿出示例代码并将其放入一个新问题,提供更多细节并询问它为什么不起作用? (3认同)
  • 请注意,这使用操作系统查找,它不一定执行 DNS 查找,并且应该知道自己的主 IP 地址... (2认同)

Jan*_*ůna 191

https://github.com/indutny/node-ip

var ip = require("ip");
console.dir ( ip.address() );
Run Code Online (Sandbox Code Playgroud)

  • @majidarif我不承认这是不良文档的有效借口 (10认同)
  • 这非常好用.获取IP地址实际上是一个单行.优秀. (6认同)
  • 它没有提供所有适配器的IP地址.如果安装了Docker,它会提供vEthernet docker地址而不是实际的以太网地址 (5认同)
  • 这个包的文档不清楚...我也可以得到广播地址,还是我必须自己提供? (2认同)
  • 这个模块有 416 行和 10Kb 只是为了获取 IP 地址......有点大材小用 (2认同)

Edo*_*rdo 56

您可以使用os模块找到您机器的任何IP - 这是NodeJS 的原生 IP

var os = require( 'os' );

var networkInterfaces = os.networkInterfaces( );

console.log( networkInterfaces );
Run Code Online (Sandbox Code Playgroud)

你需要做的就是调用os.networkInterfaces(),你将获得一个易于管理的列表 - 比联盟运行ifconfig更容易

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

最好

爱德华多

  • 很棒的答案.var ip = networkInterfaces ['eth0'] [0] ['address'] (7认同)
  • 为我工作。`var address = networkInterfaces ['venet0:0'] [0] .address` (3认同)

use*_*621 33

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

(仅在MacOS 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 OSs without 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 IPs
            var matches = stdout.match(filterRE);
            // JS has no lookbehind REs, 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);
        });
    };
})();
Run Code Online (Sandbox Code Playgroud)

用法示例:

getNetworkIP(function (error, ip) {
    console.log(ip);
    if (error) {
        console.log('error:', error);
    }
}, false);
Run Code Online (Sandbox Code Playgroud)

如果第二个参数是true,该函数每次都会执行一次系统调用; 否则使用缓存的值.


更新后的版本

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

在Ubuntu 11.04和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);
        });
    };
})();
Run Code Online (Sandbox Code Playgroud)

更新版本的用法示例

getNetworkIPs(function (error, ip) {
console.log(ip);
if (error) {
    console.log('error:', error);
}
}, false);
Run Code Online (Sandbox Code Playgroud)


jhu*_*man 28

这是我获取本地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';
}
Run Code Online (Sandbox Code Playgroud)


小智 27

安装名为ip like的模块

npm install ip
Run Code Online (Sandbox Code Playgroud)

然后使用此代码.

var ip = require("ip");
console.log( ip.address() );
Run Code Online (Sandbox Code Playgroud)

  • 这将返回127.0.0.1 (4认同)

Jim*_*bly 22

调用ifconfig是非常依赖于平台的,并且网络层确实知道套接字所在的IP地址,所以最好是问它.Node不公开直接执行此操作的方法,但您可以打开任何套接字,并询问正在使用的本地IP地址.例如,打开www.google.com的套接字:

var net = require('net');
function getNetworkIP(callback) {
  var socket = net.createConnection(80, 'www.google.com');
  socket.on('connect', function() {
    callback(undefined, socket.address().address);
    socket.end();
  });
  socket.on('error', function(e) {
    callback(e, 'error');
  });
}
Run Code Online (Sandbox Code Playgroud)

使用案例:

getNetworkIP(function (error, ip) {
    console.log(ip);
    if (error) {
        console.log('error:', error);
    }
});
Run Code Online (Sandbox Code Playgroud)


Tor*_*amo 19

您的本地IP始终为127.0.0.1.

然后是网络IP,您可以从ifconfig(*nix)或ipconfig(win)获得.这仅在本地网络中有用.

然后是你的外部/公共IP,只有你能以某种方式询问路由器才能得到它,或者你可以设置一个外部服务,它会在收到请求时返回客户端IP地址.还有其他此类服务,如whatismyip.com.

在某些情况下(例如,如果您有WAN连接),网络IP和公共IP是相同的,并且都可以在外部用于到达您的计算机.

如果您的网络和公共IP不同,您可能需要让网络路由器转发到网络ip的所有传入连接.


2013年更新:

现在有一种新的方法,您可以检查连接的套接字对象是否有一个名为的属性localAddress,例如net.socket.localAddress.它返回套接字末尾的地址.

最简单的方法是打开一个随机端口并监听它,然后获取你的地址并关闭套接字.


2015年更新:

以前不再适用了.


MK.*_*MK. 14

我可能来晚了这个问题,但如果有人想要一个单行 ES6 解决方案来获取 IP 地址数组,那么这应该对你有帮助:

Object.values(require("os").networkInterfaces())
    .flat()
    .filter(({ family, internal }) => family === "IPv4" && !internal)
    .map(({ address }) => address)
Run Code Online (Sandbox Code Playgroud)

作为

Object.values(require("os").networkInterfaces())
Run Code Online (Sandbox Code Playgroud)

将返回一个数组数组,因此flat()用于将其展平为单个数组

.filter(({ family, internal }) => family === "IPv4" && !internal)
Run Code Online (Sandbox Code Playgroud)

将过滤数组以仅包含 IPv4 地址(如果不是内部地址)

最后

.map(({ address }) => address)
Run Code Online (Sandbox Code Playgroud)

将仅返回过滤数组的 IPv4 地址

所以结果是[ '192.168.xx.xx' ]

如果需要或更改过滤条件,您可以获取该数组的第一个索引

OS使用的是Windows


KAR*_*N.A 12

使用npm ip模块

var ip = require('ip');

console.log(ip.address());

> '192.168.0.117'
Run Code Online (Sandbox Code Playgroud)

  • 我不知道如何告诉现在登陆此页面的用户这是当前上下文中唯一合适的选项。 (4认同)

vau*_*ult 11

下划线lodash的正确一个衬里是:

var ip = require('underscore')
    .chain(require('os').networkInterfaces())
    .values()
    .flatten()
    .find({family: 'IPv4', internal: false})
    .value()
    .address;
Run Code Online (Sandbox Code Playgroud)

  • 您可以使用:`.find({family:'IPv4',internal:false})`以及更短的更优雅的代码 (3认同)

小智 11

这可能是最干净、最简单的答案,没有依赖项,并且适用于所有平台。

const { lookup } = require('dns').promises;
const { hostname } = require('os');

async function getMyIPAddress(options) {
  return (await lookup(hostname(), options))
    .address;
}
Run Code Online (Sandbox Code Playgroud)


mpe*_*pen 8

我只知道我想要IP地址开头192.168..这段代码将为您提供:

function getLocalIp() {
    const os = require('os');

    for(let addresses of Object.values(os.networkInterfaces())) {
        for(let add of addresses) {
            if(add.address.startsWith('192.168.')) {
                return add.address;
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

当然,如果您正在寻找不同的数字,您可以更改数字.


Tar*_*ngh 7

仅适用于 macOS 第一个本地主机地址的一个衬垫。

在 macOS 上开发应用程序时,您想在手机上测试它,并且需要您的应用程序自动选择本地主机 IP 地址。

require('os').networkInterfaces().en0.find(elm => elm.family=='IPv4').address
Run Code Online (Sandbox Code Playgroud)

这只是提到如何自动找出IP地址。要测试这一点,您可以转到终端点击

node
os.networkInterfaces().en0.find(elm => elm.family=='IPv4').address
Run Code Online (Sandbox Code Playgroud)

输出将是您的本地主机 IP 地址。


Soy*_*oes 6

对于 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);
Run Code Online (Sandbox Code Playgroud)

结果将是这样的:

['192.168.3.2', '192.168.2.1']
Run Code Online (Sandbox Code Playgroud)


Ben*_*son 6

我编写了一个Node.js模块,通过查看哪个网络接口包含您的默认网关来确定您的本地IP地址.

这比从os.networkInterfaces()主机名中选择接口或DNS查找更可靠.它能够忽略VMware虚拟接口,环回和VPN接口,并且可以在Windows,Linux,Mac OS和FreeBSD上运行.在引擎盖下,它执行route.exenetstat解析输出.

var localIpV4Address = require("local-ipv4-address");

localIpV4Address().then(function(ipAddress){
    console.log("My IP address is " + ipAddress);
    // My IP address is 10.4.4.137 
});
Run Code Online (Sandbox Code Playgroud)


小智 6

我只使用 Node.js 就可以做到这一点。

作为 Node.js:

var os = require( 'os' );
var networkInterfaces = Object.values(os.networkInterfaces())
    .reduce((r,a) => {
        r = r.concat(a)
        return r;
    }, [])
    .filter(({family, address}) => {
        return family.toLowerCase().indexOf('v4') >= 0 &&
            address !== '127.0.0.1'
    })
    .map(({address}) => address);
var ipAddresses = networkInterfaces.join(', ')
console.log(ipAddresses);
Run Code Online (Sandbox Code Playgroud)

作为 Bash 脚本(需要安装 Node.js)

function ifconfig2 ()
{
    node -e """
        var os = require( 'os' );
        var networkInterfaces = Object.values(os.networkInterfaces())
            .reduce((r,a)=>{
                r = r.concat(a)
                return r;
            }, [])
            .filter(({family, address}) => {
                return family.toLowerCase().indexOf('v4') >= 0 &&
                    address !== '127.0.0.1'
            })
            .map(({address}) => address);
        var ipAddresses = networkInterfaces.join(', ')
        console.log(ipAddresses);
    """
}
Run Code Online (Sandbox Code Playgroud)


Kyl*_*ris 5

对于任何对简洁感兴趣的人,这里有一些“one-liners”,它们不需要不属于标准 Node.js 安装的插件/依赖项:

eth0 的公共 IPv4 和 IPv6 地址作为数组:

var ips = require('os').networkInterfaces().eth0.map(function(interface) {
    return interface.address;
});
Run Code Online (Sandbox Code Playgroud)

eth0(通常是 IPv4)的第一个公共 IP 地址作为字符串:

var ip = require('os').networkInterfaces().eth0[0].address;
Run Code Online (Sandbox Code Playgroud)


Sim*_*Ami 5

这是vanilla 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';
}
Run Code Online (Sandbox Code Playgroud)