Получить локальный IP-адрес в node.js

У меня на компьютере запущена простая программа node.js, и я хочу получить локальный IP-адрес ПК, на котором запущена моя программа. Как мне получить его с помощью node.js?

41 ответ

Решение
'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

os.networkInterfaces на данный момент не работает на окнах. Запускать программы для анализа результатов кажется немного сомнительным. Вот что я использую.

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

Это должно вернуть ваш первый сетевой интерфейс локального IP.

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

var ip = require("ip");
console.dir ( ip.address() );

Любой IP-адрес вашей машины вы можете найти с помощью модуля os - и это родной для NodeJS

var os = require( 'os' );

var networkInterfaces = os.networkInterfaces( );

console.log( networkInterfaces );

Все, что вам нужно сделать, это вызвать os.networkInterfaces(), и вы получите простой управляемый список - проще, чем запуск ifconfig по лигам

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

Лучший

Эдоардо

Установите модуль под названием ip like

npm install ip

затем используйте этот код.

var ip = require("ip");
console.log( ip.address() );

Вот мой метод получения локального 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';
}

Вот фрагмент кода 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);
        });
    };
})();

Пример использования:

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

Если второй параметр 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);
        });
    };
})();

Пример использования для обновленной версии

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

Вызов 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');
  });
}

Случай использования:

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

Использовать модуль npm ip

var ip = require('ip');

console.log(ip.address());

> '192.168.0.117'

Ваш локальный IP-адрес всегда 127.0.0.1.

Тогда есть сетевой IP, который вы можете получить от ifconfig (*nix) или ipconfig (выиграть). Это полезно только внутри локальной сети.

Кроме того, существует ваш внешний / публичный IP-адрес, который вы можете получить только в том случае, если вы каким-либо образом попросите маршрутизатор указать его, или вы можете настроить внешнюю службу, которая будет возвращать IP-адрес клиента всякий раз, когда он получает запрос. Существуют и другие подобные сервисы, такие как whatismyip.com.

В некоторых случаях (например, если у вас есть WAN-соединение), IP-адрес сети и общедоступный IP-адрес совпадают, и оба могут использоваться для доступа к вашему компьютеру.

Если ваша сеть и общедоступные IP-адреса различаются, вам может потребоваться, чтобы сетевой маршрутизатор переадресовывал все входящие соединения на ваш ip сети.


Обновление 2013:

Теперь есть новый способ сделать это, вы можете проверить объект сокета вашего соединения для свойства, называемого localAddressнапример, net.socket.localAddress, Он возвращает адрес на вашем конце сокета.

Самый простой способ - просто открыть случайный порт и прослушать его, затем получить свой адрес и закрыть сокет.


Обновление 2015:

Предыдущее больше не работает.

Правильный один лайнер для подчеркивания и lodash:

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

Вот что может быть самым чистым и простым ответом без зависимостей, который работает на всех платформах.

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

async function getMyIPAddress(options) {
  return (await lookup(hostname(), options))
    .address;
}

Все, что я знаю, я хотел, чтобы 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;
            }
        }
    }
}

Конечно, вы можете просто изменить цифры, если вы ищете другой.

Я смог сделать это, используя только узел JS

As 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 (нужен установленный узел 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);
    """
}

Я написал модуль Node.js, который определяет ваш локальный IP-адрес, посмотрев, какой сетевой интерфейс содержит ваш шлюз по умолчанию.

Это более надежно, чем выбор интерфейса из os.networkInterfaces() или DNS поиск имени хоста. Он способен игнорировать виртуальные интерфейсы VMware, петлевые и VPN-интерфейсы и работает в Windows, Linux, Mac OS и FreeBSD. Под капотом он выполняет route.exe или же netstat и анализирует вывод.

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 
});

Для 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' ]

Вот упрощенная версия ванильного 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:

Общедоступные IPv4 и IPv6 из eth0 в качестве массива:

var ips = require('os').networkInterfaces().eth0.map(function(interface) { 
    return interface.address;
});

Первый публичный IP-адрес eth0 (обычно IPv4) в виде строки:

var ip = require('os').networkInterfaces().eth0[0].address;

Один вкладыш для MAC только по первому локальному адресу.

Когда вы разрабатываете приложения для Mac OS и хотите протестировать их на телефоне, вам нужно, чтобы ваше приложение автоматически выбирало IP-адрес localhost.

require('os').networkInterfaces().en0.find(elm=>elm.family=='IPv4').address

Это просто упомянуть, как вы можете узнать IP-адрес автоматически. Чтобы проверить это, вы можете перейти к терминальному удару

node
os.networkInterfaces().en0.find(elm=>elm.family=='IPv4').address

вывод будет ваш IP-адрес localhost.

Следующее решение работает для меня

const ip = Object.values(require("os").networkInterfaces())
        .flat()
        .filter((item) => !item.internal && item.family === "IPv4")
        .find(Boolean).address;

Вот вариант вышеупомянутых примеров. Это требует фильтрации интерфейсов vMware и т. Д. Если вы не передадите индекс, он вернет все адреса, в противном случае вы можете установить его по умолчанию на 0, а затем просто передать null, чтобы получить все, но вы разберетесь с этим. Вы также можете передать другой аргумент для фильтра регулярных выражений, если хотите добавить

    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;
}

Я, вероятно, опоздал с этим вопросом, но в случае, если кто-то хочет получить однострочное решение ES6 для получения массива IP-адресов, это должно вам помочь:

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

В виде

      Object.values(require("os").networkInterfaces())

вернет массив массивов, поэтому flat() используется для сглаживания его в единый массив

      .filter(({ family, internal }) => family === "IPv4" && !internal)

Будет фильтровать массив, чтобы включить только адреса IPv4, и если он не внутренний

Ну наконец то

      .map(({ address }) => address)

Вернет только IPv4-адрес отфильтрованного массива

так результат будет [ '192.168.xx.xx' ]

затем вы можете получить первый индекс этого массива, если хотите, или изменить условие фильтра

OS используется Windows

Google направил меня на этот вопрос во время поиска "node.js get server ip", поэтому давайте дадим альтернативный ответ тем, кто пытается добиться этого в своей серверной программе node.js (может быть, в случае с оригинальным постером).

В наиболее тривиальном случае, когда сервер связан только с одним IP-адресом, не нужно определять IP-адрес, поскольку мы уже знаем, с каким адресом мы его связываем (например, второй параметр передается в listen() функция).

В менее тривиальном случае, когда сервер привязан к нескольким IP-адресам, нам может потребоваться определить IP-адрес интерфейса, к которому подключен клиент. И как кратко предложил Tor Valamo, в настоящее время мы можем легко получить эту информацию из подключенного сокета и его localAddress имущество.

Например, если программа является веб-сервером:

var http = require("http")

http.createServer(function (req, res) {
    console.log(req.socket.localAddress)
    res.end(req.socket.localAddress)
}).listen(8000)

И если это общий TCP-сервер:

var net = require("net")

net.createServer(function (socket) {
    console.log(socket.localAddress)
    socket.end(socket.localAddress)
}).listen(8000)

При запуске серверной программы это решение предлагает очень высокую мобильность, точность и эффективность.

Для более подробной информации смотрите:

Если вам нравится вся эта краткость, то здесь используется 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);

Основываясь на комментарии выше, вот что работает для текущей версии Node:

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() теперь возвращает объект вместо массива.

Много раз я обнаружил, что доступно несколько внутренних и внешних интерфейсов (пример: 10.0.75.1, 172.100.0.1, 192.168.2.3), и это внешний, который я действительно после (172.100.0.1).

В случае, если у кого-то еще есть подобные проблемы, вот еще один вариант, который, надеюсь, может быть полезным...

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;

Вот небольшая аккуратная строчка для вас, которая делает это функционально:

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];

Надеюсь это поможет

var os = require( 'os' );
var networkInterfaces = os.networkInterfaces( );
var arr = networkInterfaces['Local Area Connection 3']
var ip = arr[1].address;

Вот мой вариант, который позволяет получать адреса IPv4 и IPv6 переносимым способом:

/**
 * 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;
};

Вот версия 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

Пример вывода для 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' } }

Это модификация принятого ответа, которая не учитывает IP-адреса vEthernet, такие как Docker и т. Д.

/**
 * Get local IP, while ignoring vEthernet IPs (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 adress
            // console.log(ifname, iface.address);
         }
         ++alias;
         localIP = iface.address;
      }
   });
});
console.log(localIP);

Это вернет IP как 192.168.2.169 вместо 10.55.1.1

Другие вопросы по тегам