409 votes

Obtenir l'adresse IP locale dans Node.js

J'ai un programme Node.js simple qui tourne sur ma machine et je veux obtenir l'adresse IP locale d'un PC sur lequel mon programme tourne. Comment puis-je l'obtenir avec Node.js ?

1 votes

Des éléments de réflexion à vérifier joeyh.name/code/moreutils y github.com/polotek/procstreams . Je ne quitte jamais la maison sans eux.

0 votes

549voto

nodyou Points 906

Cette information peut être trouvée dans os.networkInterfaces() Un objet qui associe les noms des interfaces réseau à leurs propriétés (de sorte qu'une interface peut, par exemple, avoir plusieurs adresses) :

'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
        if (net.family === 'IPv4' && !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"

20 votes

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

0 votes

La sixième ligne devrait être if( details.family=='IPv4' && details.internal === false ) { si vous voulez juste des IPs externes.

4 votes

@CarterCole vous avez besoin d'un appel supplémentaire à .values() avant d'aplatir.

250voto

Xedecimal Points 790

L'exécution de programmes pour analyser les résultats semble un peu incertaine. Voici ce que j'utilise.

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

Vous devriez obtenir l'adresse IP locale de votre première interface réseau.

5 votes

@HermannIngjaldsson : Cette critique n'est pas très informative. Pourriez-vous être plus précis ? Peut-être prendre le code d'exemple et le mettre dans une nouvelle question en fournissant plus de détails et en demandant pourquoi il ne fonctionne pas ?

13 votes

Ce n'est pas toujours une bonne idée d'utiliser la recherche DNS, car elle peut renvoyer des informations erronées (c'est-à-dire des données mises en cache). L'utilisation de 'os.networkInterfaces' est une meilleure idée à mon avis.

4 votes

L'utilisation du DNS fonctionne si votre serveur a une entrée DNS quelque part. Cependant, dans beaucoup d'applications, il n'y a pas d'entrée DNS (par exemple, mon ordinateur portable). os.networkInterfaces() est probablement la meilleure solution.

73voto

Edoardo Points 101

Toute adresse IP de votre machine que vous pouvez trouver en utilisant l'option os module - et c'est indigène à Node.js :

var os = require('os');

var networkInterfaces = os.networkInterfaces();

console.log(networkInterfaces);

Il vous suffit d'appeler _os.networkInterfaces()_ et vous obtiendrez une liste facile à gérer - plus facile que de courir ifconfig par les ligues.

11 votes

Réponse géniale. var ip = networkInterfaces['eth0'][0]['address']

0 votes

Bien que cela semble génial parce que simple, son efficacité réelle dépend probablement de la configuration de votre réseau. Par exemple, il n'y a pas de eth0 dans la configuration par défaut d'OS X, c'est en0.

3 votes

Ça marche pour moi. var address = networkInterfaces['venet0:0'][0].address

34voto

Pumbaa80 Points 27066

Voici un extrait de code Node.js qui analysera la sortie de l'application ifconfig et renvoie (de manière asynchrone) la première adresse IP trouvée :

(Il a été testé sur Mac OS X v10.6 (Snow Leopard) uniquement ; j'espère que cela fonctionne aussi sous 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);
        });
    };
})();

Exemple d'utilisation :

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

Si le deuxième paramètre est true la fonction exécutera un appel système à chaque fois ; sinon, la valeur mise en cache est utilisée.


Version actualisée

Renvoie un tableau de toutes les adresses de réseaux locaux.

Testé sur Ubuntu 11.04 (Natty Narwhal) et 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);
        });
    };
})();

Exemple d'utilisation de la version mise à jour

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

0 votes

Testé à l'instant sur OSX Lion, parfait. Merci beaucoup !

0 votes

J'ai dû supprimer le trait d'union après le mot "IP" dans votre regexp Windows, car mon résultat ne comportait pas de trait d'union (j'utilise Windows XP 32 bits). Je ne sais pas si c'était une faute de frappe ou si votre version de Windows produit vraiment un trait d'union après "IP", mais par sécurité, je suppose qu'il peut être rendu facultatif : filterRE = /\bIP-?[^:\r\n]+:\s*([^\s]+)/g; . A part ça, super script, un vrai sauveur. Merci beaucoup !

0 votes

@jSepia : C'est probablement une question de localisation. Windows allemand imprime "IP-Adresse" ;)

24voto

Jimbly Points 111

L'appel à ifconfig est très dépendant de la plate-forme, et la couche réseau sait sur quelles adresses IP se trouve une socket, donc le mieux est de lui demander.

Node.js n'expose pas une méthode directe pour faire cela, mais vous pouvez ouvrir n'importe quel socket, et demander quelle adresse IP locale est utilisée. Par exemple, en ouvrant un socket vers 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');
  });
}

Cas d'utilisation :

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

0 votes

Au cas où vous vous poseriez la question, cela ne donne pas nécessairement l'adresse IP publique que le monde entier voit.

0 votes

Ce serait une bonne solution si elle ne dépendait pas de la connexion internet et de sa vitesse .

0 votes

Dans mon cas, cette solution est parfaite, car j'ai besoin de connaître l'IP de l'interface sur laquelle une requête particulière est envoyée.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X