我有一个简单的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
也是你的朋友;-)
希望能有所帮助!
其他回答
这些信息可以在os.networkInterfaces()中找到,这是一个对象,它将网络接口名称映射到它的属性(例如,一个接口可以有几个地址):
'use strict';
const { networkInterfaces } = require('os');
const nets = networkInterfaces();
const results = Object.create(null); // Or just '{}', an empty object
for (const name of Object.keys(nets)) {
for (const net of nets[name]) {
// Skip over non-IPv4 and internal (i.e. 127.0.0.1) addresses
// 'IPv4' is in Node <= 17, from 18 it's a number 4 or 6
const familyV4Value = typeof net.family === 'string' ? 'IPv4' : 4
if (net.family === familyV4Value && !net.internal) {
if (!results[name]) {
results[name] = [];
}
results[name].push(net.address);
}
}
}
// 'results'
{
"en0": [
"192.168.1.101"
],
"eth0": [
"10.0.0.101"
],
"<network name>": [
"<ip>",
"<ip alias>",
"<ip alias>",
...
]
}
// results["en0"][0]
"192.168.1.101"
下面是一段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);
根据注释,以下是当前版本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()现在返回一个对象而不是数组。
我只用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);
作为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);
"""
}
对于Underscore.js和Lodash,正确的一行代码是:
var ip = require('underscore')
.chain(require('os').networkInterfaces())
.values()
.flatten()
.find({family: 'IPv4', internal: false})
.value()
.address;
推荐文章
- 如何通过history. pushstate获得历史变化的通知?
- 使用jQuery改变输入字段的类型
- 在JavaScript中,什么相当于Java的Thread.sleep() ?
- 使用jQuery以像素为整数填充或边距值
- 检查是否选择了jQuery选项,如果没有选择默认值
- Next.js React应用中没有定义Window
- 如何重置笑话模拟函数调用计数之前,每次测试
- 如何强制一个功能React组件渲染?
- 错误:无法找到模块“webpack”
- 在javascript中从平面数组构建树数组
- 将Dropzone.js与其他字段集成到现有的HTML表单中
- 如何在AngularJS中观察路由变化?
- JavaScript DOM删除元素
- 将dd-mm-yyyy字符串转换为日期
- Javascript复选框onChange