Mam prosty program node.js uruchomiony na moim komputerze i chcę uzyskać lokalny adres IP komputera, na którym działa mój program. Jak mogę go uzyskać za pomocą node.js?
Mam prosty program node.js uruchomiony na moim komputerze i chcę uzyskać lokalny adres IP komputera, na którym działa mój program. Jak mogę go uzyskać za pomocą node.js?
Odpowiedzi:
'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
if( details.family=='IPv4' && details.internal === false ) {
jeśli chcesz tylko zewnętrznych adresów IP.
Object.values(require('os').networkInterfaces()).reduce((r, list) => r.concat(list.reduce((rr, i) => rr.concat(i.family==='IPv4' && !i.internal && i.address || []), [])), [])
os.networkInterfaces na razie nie działa w systemie Windows. Uruchamianie programów do analizowania wyników wydaje się nieco niepewne. Oto czego używam.
require('dns').lookup(require('os').hostname(), function (err, add, fam) {
console.log('addr: '+add);
})
Powinno to zwrócić pierwszy lokalny interfejs sieciowy IP.
https://github.com/indutny/node-ip
var ip = require("ip");
console.dir ( ip.address() );
Dowolny adres IP twojego komputera, który możesz znaleźć za pomocą modułu os - i to jest natywne dla NodeJS
var os = require( 'os' );
var networkInterfaces = os.networkInterfaces( );
console.log( networkInterfaces );
Wystarczy zadzwonić do os.networkInterfaces (), a otrzymasz łatwą do zarządzania listę - łatwiejszą niż uruchamianie ifconfig przez ligi
http://nodejs.org/api/os.html#os_os_networkinterfaces
Najlepsza
Edoardo
var address = networkInterfaces['venet0:0'][0].address
Oto fragment kodu node.js, który przeanalizuje dane wyjściowe ifconfig
i (asynchronicznie) zwróci pierwszy znaleziony adres IP:
(testowane tylko w systemie MacOS Snow Leopard; mam nadzieję, że działa również na systemie 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);
});
};
})();
Przykład użycia:
getNetworkIP(function (error, ip) {
console.log(ip);
if (error) {
console.log('error:', error);
}
}, false);
Jeśli drugim parametrem jest true
, funkcja będzie wykonywać wywołanie systemowe za każdym razem; w przeciwnym razie używana jest wartość buforowana.
Zwraca tablicę wszystkich adresów sieci lokalnej.
Testowane na Ubuntu 11.04 i 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);
filterRE = /\bIP-?[^:\r\n]+:\s*([^\s]+)/g;
. Poza tym świetny skrypt, prawdziwy ratownik. Wielkie dzięki!
Oto moja użyteczna metoda uzyskiwania lokalnego adresu IP, zakładając, że szukasz adresu IPv4, a urządzenie ma tylko jeden prawdziwy interfejs sieciowy. Można go łatwo refaktoryzować, aby zwrócić tablicę adresów IP dla maszyn z wieloma interfejsami.
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';
}
getLocalIP = (interfaceName = "en0",version = "IPv4")-> iface = require('os').networkInterfaces()[interfaceName] for alias in iface if (alias.family == version && !alias.internal) return alias.address return "0.0.0.0"
Zainstaluj moduł o nazwie ip like
npm install ip
następnie użyj tego kodu.
var ip = require("ip");
console.log( ip.address() );
Wywołanie ifconfig jest bardzo zależne od platformy, a warstwa sieciowa wie, na jakich adresach IP znajduje się gniazdo, więc najlepiej zapytać. Węzeł nie ujawnia bezpośredniej metody tego, ale możesz otworzyć dowolne gniazdo i zapytać, jaki jest używany lokalny adres IP. Na przykład otwarcie gniazda na 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');
});
}
Przypadek użycia:
getNetworkIP(function (error, ip) {
console.log(ip);
if (error) {
console.log('error:', error);
}
});
Twój lokalny adres IP to zawsze 127.0.0.1.
Następnie jest adres IP sieci, który można uzyskać z ifconfig
(* nix) lub ipconfig
(win). Jest to przydatne tylko w sieci lokalnej.
Następnie jest twój zewnętrzny / publiczny adres IP, który możesz uzyskać tylko wtedy, gdy możesz poprosić o niego router, lub możesz skonfigurować usługę zewnętrzną, która zwraca adres IP klienta, gdy tylko otrzyma żądanie. Istnieją również inne takie usługi, takie jak whatismyip.com.
W niektórych przypadkach (na przykład, jeśli masz połączenie WAN), IP sieci i publiczny IP są takie same i mogą być używane zewnętrznie, aby połączyć się z komputerem.
Jeśli sieć i publiczne adresy IP są różne, może być konieczne, aby router sieciowy przekazywał wszystkie połączenia przychodzące do twojego adresu IP sieci.
Aktualizacja 2013:
Jest teraz nowy sposób na zrobienie tego, możesz sprawdzić obiekt gniazda swojego połączenia pod kątem właściwości o nazwie localAddress
np net.socket.localAddress
. Zwraca adres na twoim końcu gniazda.
Najprościej jest po prostu otworzyć losowy port i nasłuchiwać, a następnie uzyskać adres i zamknąć gniazdo.
Aktualizacja 2015:
Poprzedni nie działa.
ifconfig
lub ipconfig
przeanalizować ciąg odpowiedzi?
ifconfig
net.socket
zwroty undefined
z 2015 roku, więc „nowy sposób robienia tego” już nie działa. Istnieje net.Socket
, ale nie ma localAddress
właściwości.
użyj npm modułu ip
var ip = require('ip');
console.log(ip.address());
> '192.168.0.117'
Prawidłowa jedna linijka zarówno dla podkreślenia, jak i dla rzęs to:
var ip = require('underscore')
.chain(require('os').networkInterfaces())
.values()
.flatten()
.find({family: 'IPv4', internal: false})
.value()
.address;
.find({family: 'IPv4', internal: false})
również dla krótszego, bardziej eleganckiego kodu
Oto najczystsza i najprostsza odpowiedź bez zależności, która działa na wszystkich platformach.
const { lookup } = require('dns').promises;
const { hostname } = require('os');
async function getMyIPAddress(options) {
return (await lookup(hostname(), options))
.address;
}
Wiem tylko, że chciałem, aby adres IP zaczynał się od 192.168.
. Ten kod da ci, że:
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;
}
}
}
}
Oczywiście możesz po prostu zmienić liczby, jeśli szukasz innego.
192.168
?
192.168.
tego, dlatego właśnie to wybrałem.
w systemach Linux i MacOS, jeśli chcesz uzyskać adresy IP w sposób synchroniczny, wypróbuj to.
var ips = require('child_process').execSync("ifconfig | grep inet | grep -v inet6 | awk '{gsub(/addr:/,\"\");print $2}'").toString().trim().split("\n");
console.log(ips);
wynikiem będzie coś takiego.
[ '192.168.3.2', '192.168.2.1' ]
Napisałem moduł Node.js, który określa lokalny adres IP, sprawdzając, który interfejs sieciowy zawiera domyślną bramę.
Jest to bardziej niezawodne niż wybieranie interfejsu os.networkInterfaces()
lub wyszukiwania DNS nazwy hosta. Jest w stanie ignorować interfejsy wirtualne VMware, sprzężenia zwrotne i interfejsy VPN, i działa w systemach Windows, Linux, Mac OS i FreeBSD. Pod maską wykonuje route.exe
lub netstat
analizuje dane wyjściowe.
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
});
Oto uproszczona wersja javascript waniliowego, aby uzyskać pojedynczy adres 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';
}
Dla każdego, kto jest zainteresowany zwięzłością, oto kilka „linków”, które nie wymagają wtyczek / zależności, które nie są częścią standardowej instalacji Węzła:
Publiczny IPv4 i IPv6 eth0 jako macierz:
var ips = require('os').networkInterfaces().eth0.map(function(interface) {
return interface.address;
});
Pierwszy publiczny adres IP eth0 (zwykle IPv4) jako ciąg znaków:
var ip = require('os').networkInterfaces().eth0[0].address;
en0
i en1
dla Ethernetu i Wi-Fi. W systemie Windows mam Local Area Connection
i Wireless Network Connection
.
Google skierowało mnie do tego pytania, wyszukując hasło „node.js get server ip” , dlatego podajmy alternatywną odpowiedź dla tych, którzy próbują to osiągnąć w programie serwera node.js (może tak być w przypadku oryginalnego plakatu).
W najbardziej trywialnym przypadku, gdy serwer jest powiązany tylko z jednym adresem IP, nie powinno być potrzeby określania adresu IP, ponieważ już wiemy, do którego adresu go przypisaliśmy (np. Drugi parametr przekazany do listen()
funkcji).
W mniej trywialnym przypadku, gdy serwer jest powiązany z wieloma adresami IP, może być konieczne określenie adresu IP interfejsu, do którego podłączony jest klient. I jak krótko sugeruje Tor Valamo, w dzisiejszych czasach możemy łatwo uzyskać te informacje z podłączonego gniazda i jego localAddress
właściwości.
Na przykład, jeśli program jest serwerem WWW:
var http = require("http")
http.createServer(function (req, res) {
console.log(req.socket.localAddress)
res.end(req.socket.localAddress)
}).listen(8000)
A jeśli jest to ogólny serwer TCP:
var net = require("net")
net.createServer(function (socket) {
console.log(socket.localAddress)
socket.end(socket.localAddress)
}).listen(8000)
Podczas uruchamiania programu serwerowego to rozwiązanie oferuje bardzo wysoką przenośność, dokładność i wydajność.
Aby uzyskać więcej informacji, zobacz:
Na podstawie powyższego komentarza oto, co działa w bieżącej wersji węzła:
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();
W komentarzu do jednej z powyższych odpowiedzi brakowało połączenia z values()
. Wygląda na to, że os.networkInterfaces()
teraz zwraca obiekt zamiast tablicy.
_.chain(..)
Można ponownie zapisać jako _(...)
The .filter(..)
można ponownie zapisać jako .where({family: 'IPv4', internal: false})
i można upuszczać ostateczna value()
, ponieważ .first()
zrobi to za ciebie podczas łączenia.
Oto odmiana powyższych przykładów. Dba o to, aby odfiltrować interfejsy vMware itp. Jeśli nie przejdziesz indeksu, zwróci on wszystkie adresy, w przeciwnym razie możesz ustawić wartość domyślną na 0, a następnie po prostu podać wartość null, aby uzyskać wszystko, ale to załatwisz. Możesz również podać inny argument dla filtru wyrażenia regularnego, jeśli masz taką skłonność do dodania
function getAddress(idx) {
var addresses = [],
interfaces = os.networkInterfaces(),
name, ifaces, iface;
for (name in interfaces) {
if(interfaces.hasOwnProperty(name)){
ifaces = interfaces[name];
if(!/(loopback|vmware|internal)/gi.test(name)){
for (var i = 0; i < ifaces.length; i++) {
iface = ifaces[i];
if (iface.family === 'IPv4' && !iface.internal && iface.address !== '127.0.0.1') {
addresses.push(iface.address);
}
}
}
}
}
// if an index is passed only return it.
if(idx >= 0)
return addresses[idx];
return addresses;
}
Byłem w stanie to zrobić, używając tylko węzła js
Jako węzeł 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);
Jako skrypt bash (wymaga zainstalowanego węzła 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); """ }
Oto mój wariant, który pozwala na uzyskanie adresów IPv4 i IPv6 w przenośny sposób:
/**
* Collects information about the local IPv4/IPv6 addresses of
* every network interface on the local computer.
* Returns an object with the network interface name as the first-level key and
* "IPv4" or "IPv6" as the second-level key.
* For example you can use getLocalIPs().eth0.IPv6 to get the IPv6 address
* (as string) of eth0
*/
getLocalIPs = function () {
var addrInfo, ifaceDetails, _len;
var localIPInfo = {};
//Get the network interfaces
var networkInterfaces = require('os').networkInterfaces();
//Iterate over the network interfaces
for (var ifaceName in networkInterfaces) {
ifaceDetails = networkInterfaces[ifaceName];
//Iterate over all interface details
for (var _i = 0, _len = ifaceDetails.length; _i < _len; _i++) {
addrInfo = ifaceDetails[_i];
if (addrInfo.family === 'IPv4') {
//Extract the IPv4 address
if (!localIPInfo[ifaceName]) {
localIPInfo[ifaceName] = {};
}
localIPInfo[ifaceName].IPv4 = addrInfo.address;
} else if (addrInfo.family === 'IPv6') {
//Extract the IPv6 address
if (!localIPInfo[ifaceName]) {
localIPInfo[ifaceName] = {};
}
localIPInfo[ifaceName].IPv6 = addrInfo.address;
}
}
}
return localIPInfo;
};
Oto wersja tej samej funkcji CoffeeScript:
getLocalIPs = () =>
###
Collects information about the local IPv4/IPv6 addresses of
every network interface on the local computer.
Returns an object with the network interface name as the first-level key and
"IPv4" or "IPv6" as the second-level key.
For example you can use getLocalIPs().eth0.IPv6 to get the IPv6 address
(as string) of eth0
###
networkInterfaces = require('os').networkInterfaces();
localIPInfo = {}
for ifaceName, ifaceDetails of networkInterfaces
for addrInfo in ifaceDetails
if addrInfo.family=='IPv4'
if !localIPInfo[ifaceName]
localIPInfo[ifaceName] = {}
localIPInfo[ifaceName].IPv4 = addrInfo.address
else if addrInfo.family=='IPv6'
if !localIPInfo[ifaceName]
localIPInfo[ifaceName] = {}
localIPInfo[ifaceName].IPv6 = addrInfo.address
return localIPInfo
Przykładowe dane wyjściowe dla console.log(getLocalIPs())
{ lo: { IPv4: '127.0.0.1', IPv6: '::1' },
wlan0: { IPv4: '192.168.178.21', IPv6: 'fe80::aa1a:2eee:feba:1c39' },
tap0: { IPv4: '10.1.1.7', IPv6: 'fe80::ddf1:a9a1:1242:bc9b' } }
Jeśli interesuje Cię cała zwięzłość, tutaj używa lodash :
var os = require('os');
var _ = require('lodash');
var firstLocalIp = _(os.networkInterfaces()).values().flatten().where({ family: 'IPv4', internal: false }).pluck('address').first();
console.log('First local IPv4 address is ' + firstLocalIp);
Podobne do innych odpowiedzi, ale bardziej zwięzłe:
'use strict';
const interfaces = require('os').networkInterfaces();
const addresses = Object.keys(interfaces)
.reduce((results, name) => results.concat(interfaces[name]), [])
.filter((iface) => iface.family === 'IPv4' && !iface.internal)
.map((iface) => iface.address);
Object.keys(interfaces).reduce(...)
z Object.values(interfaces).flat()
i byłoby to samo.
Tworząc aplikacje na Mac OS, chcesz przetestować je na telefonie i potrzebujesz, aby aplikacja automatycznie wybrała adres IP hosta lokalnego.
require('os').networkInterfaces().en0.find(elm=>elm.family=='IPv4').address
Wystarczy wspomnieć, jak automatycznie znaleźć adres IP. Aby to przetestować, możesz przejść do terminalu hit
node
os.networkInterfaces().en0.find(elm=>elm.family=='IPv4').address
wyjście będzie Twoim adresem IP hosta lokalnego.
Oto schludny mały linijka dla ciebie, która robi to funkcjonalnie:
const ni = require('os').networkInterfaces();
Object
.keys(ni)
.map(interf =>
ni[interf].map(o => !o.internal && o.family === 'IPv4' && o.address))
.reduce((a, b) => a.concat(b))
.filter(o => o)
[0];
reduce
i zastąpić połączenie na map
z flatMap
.
Wiele razy znajduję wiele dostępnych interfejsów wewnętrznych i zewnętrznych (przykład: 10.0.75.1
, 172.100.0.1
, 192.168.2.3
), i jest to jeden zewnętrzny, że jestem naprawdę po ( 172.100.0.1
).
Jeśli ktoś ma podobne obawy, oto jeszcze jedno podejście, które, mam nadzieję, może być pomocne ...
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;
Używam node.js 0.6.5
$ node -v
v0.6.5
Oto co robię
var util = require('util');
var exec = require('child_process').exec;
function puts(error, stdout, stderr) {
util.puts(stdout);
}
exec("hostname -i", puts);
hostname -I
(wielkie litery i). Zwraca listę wszystkich przypisanych adresów IP urządzenia. Pierwszy adres IP jest tym, czego potrzebujesz. Ten adres IP jest dołączony do bieżącego interfejsu, który jest uruchomiony.
Oto wielojęzyczna wersja powyższej odpowiedzi jhurlimana:
function getIPAddresses() {
var ipAddresses = [];
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) {
ipAddresses.push(alias.address);
}
}
}
return ipAddresses;
}
Zdaję sobie sprawę, że to stary wątek, ale chciałbym zaoferować poprawę w stosunku do najwyższej odpowiedzi z następujących powodów:
dla ... w ... wyliczenie powinno zostać sprawdzone, aby upewnić się, że wyliczany obiekt zawiera właściwość, której szukasz. Ponieważ javsacript jest luźno wpisany, a for ... in ... można przekazać dowolny obiekt arbitrażowy do obsługi; bezpieczniej jest zweryfikować właściwość, której szukamy, jest dostępna.
var os = require('os'),
interfaces = os.networkInterfaces(),
address,
addresses = [],
i,
l,
interfaceId,
interfaceArray;
for (interfaceId in interfaces) {
if (interfaces.hasOwnProperty(interfaceId)) {
interfaceArray = interfaces[interfaceId];
l = interfaceArray.length;
for (i = 0; i < l; i += 1) {
address = interfaceArray[i];
if (address.family === 'IPv4' && !address.internal) {
addresses.push(address.address);
}
}
}
}
console.log(addresses);