【问题标题】:How to get my external IP address with node.js?如何使用 node.js 获取我的外部 IP 地址?
【发布时间】:2013-12-14 21:42:41
【问题描述】:

我正在使用 node.js,我需要获取我的 ISP 提供的外部 IP 地址。 有没有办法在不使用http://myexternalip.com/raw 之类的服务的情况下实现这一目标?

【问题讨论】:

  • 如果你在 NAT 后面就不行
  • 我想这是我的情况。我的笔记本电脑 IP 是 192.168.1.3,我的 wifi 路由器是 192.168.1.1,我的 ISP 提供的调制解调器 IP 是 201.15.1XX.XXX。我只想得到最后一个。
  • 不特定于节点或任何一种语言。这是一个网络路由问题,如果不连接,则无法从主机上最终确定。

标签: node.js


【解决方案1】:

可以像他们在 Python 中所做的那样来获取外部 IP,连接到某个网站并从套接字连接中获取您的详细信息:

const net = require('net');
const client = net.connect({port: 80, host:"google.com"}, () => {
  console.log('MyIP='+client.localAddress);
  console.log('MyPORT='+client.localPort);
});

*很遗憾,无法再找到原始 Python 示例作为参考。


2019 年更新: 使用来自https://whatismyipaddress.com/api的内置http库和公共API

const http = require('http');

var options = {
  host: 'ipv4bot.whatismyipaddress.com',
  port: 80,
  path: '/'
};

http.get(options, function(res) {
  console.log("status: " + res.statusCode);

  res.on("data", function(chunk) {
    console.log("BODY: " + chunk);
  });
}).on('error', function(e) {
  console.log("error: " + e.message);
});

在 Amazon AWS 服务器上使用 Node.js v0.10.48 测试

--
2021 年更新
ipv4bot 已关闭,这是另一个公共 API:

var http = require('http');

http.get({'host': 'api.ipify.org', 'port': 80, 'path': '/'}, function(resp) {
  resp.on('data', function(ip) {
    console.log("My public IP address is: " + ip);
  });
});

更多信息https://www.ipify.org/

【讨论】:

  • 这不会为我输出外部IP
  • @pixelfreak 哪个节点版本?使用 v4.4.5 对我仍然有效
  • 这输出我的本地网络/路由器192.168.xxx地址,而不是公共地址
  • @laggingreflex 哇,确实如此,我想知道它是否曾经正常工作过?我当时确实在生产服务器上使用了它......现在使用公共 api 添加了新的替代方案。
  • 截至 2021 年 11 月 10 日,ipv4bot 已关闭其公共 API,请参阅 announcement。我按照@jtlindsey 的建议切换到public-ip
【解决方案2】:

npm install --save public-ip 来自here

然后

publicIp.v4().then(ip => {
  console.log("your public ip address", ip);
});

如果你想要本地机器 ip 你可以使用this

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

【讨论】:

  • ipv4 查询对我来说每次都失败。 “查询超时”
【解决方案3】:

使用my externalip package on GitHub

externalip(function (err, ip) {
  console.log(ip); // => 8.8.8.8
});

【讨论】:

  • 制作一个几行的包来包含另一个包是很愚蠢的。另请参阅 Ade Yahya 回答此包中的内容。
  • 建议每个人都使用您的软件包将用户 IP 信息发送到中华人民共和国,这并不是很酷。
【解决方案4】:

编辑:这是在 2013 年写的……该网站已经消失了。我暂时保留示例请求代码,除非有人抱怨但寻求接受的答案。


http://fugal.net/ip.cgi 和那个类似。

或者你可以

require('http').request({
    hostname: 'fugal.net',
    path: '/ip.cgi',
    agent: false
    }, function(res) {
    if(res.statusCode != 200) {
        throw new Error('non-OK status: ' + res.statusCode);
    }
    res.setEncoding('utf-8');
    var ipAddress = '';
    res.on('data', function(chunk) { ipAddress += chunk; });
    res.on('end', function() {
        // ipAddress contains the external IP address
    });
    }).on('error', function(err) {
    throw err;
}).end();

参考:http://www.nodejs.org/api/http.html#http_http_request_options_callback

【讨论】:

  • 好的开始,但您缺少一件重要的事情:致电end。任何尝试此脚本的人,不要忘记像这样更改最后一行:}).end();
  • 网站离线
【解决方案5】:

这应该可以在没有任何外部依赖的情况下运行良好(ipify.org 除外):

var https = require('https');

var callback = function(err, ip){
    if(err){
        return console.log(err);
    }
    console.log('Our public IP is', ip);
    // do something here with the IP address
};

https.get({
    host: 'api.ipify.org',
}, function(response) {
    var ip = '';
    response.on('data', function(d) {
        ip += d;
    });
    response.on('end', function() {
        if(ip){
            callback(null, ip);
        } else {
            callback('could not get public ip address :(');
        }
    });
});

你也可以使用https://httpbin.org

获取https://httpbin.org/ip

【讨论】:

    【解决方案6】:

    只需使用超级代理

    var superagent = require('superagent');
    var getip = function () {
      superagent
        .get('http://ip.cn/')
        .set('User-Agent', 'curl/7.37.1')
        .end(function (err, res) {
          if (err) {
            console.log(err);
          }
          var ip = res.text.match(/\d+\.\d+\.\d+\.\d+/)[0];
          console.log(ip)
          // Here is the result
        });
    };
    

    【讨论】:

      【解决方案7】:

      另一个小节点模块是ext-ip。不同之处在于,您可以使用不同的响应选项,匹配您的编码风格。开箱即可使用...

      承诺

      let extIP = require('ext-ip')();
      
      extIP.get().then(ip => {
          console.log(ip);
      })
      .catch(err => {
          console.error(err);
      });
      

      活动

      let extIP = require('ext-ip')();
      
      extIP.on("ip", ip => {
          console.log(ip);
      });
      
      extIP.on("err", err => {
          console.error(err);
      });
      
      extIP();
      

      回调

      let extIP = require('ext-ip')();
      
      extIP((err, ip) => {
          if( err ){
              throw err;
          }
      
          console.log(ip);
      });
      

      【讨论】:

        【解决方案8】:

        您可以使用request-ip 包:

        const requestIp = require('request-ip');
        
        // inside middleware handler
        const ipMiddleware = function(req, res, next) {
            const clientIp = requestIp.getClientIp(req); 
            next();
        };
        

        【讨论】:

          【解决方案9】:

          根据经验,最简单的答案是,在大多数情况下,如果不使用外部服务,您将无法获取外部 IP,因为您通常位于 NAT 后面或被防火墙屏蔽。我说在大多数情况下,因为在某些情况下您可以从路由器中获取它,但它过于具体,无法提供一般性答案。

          你想要的只是在 NodeJS 中选择你最喜欢的 http 客户端,然后找到一个维护的服务器,它只用正文中的 IP 地址进行响应。您也可以使用包,但您应该查看它是否仍在使用维护的远程服务器。

          虽然已经有很多示例,但这里有一个先尝试 IPv6 然后回退到 IPv4 的示例。它利用了 axios,因为这是我所习惯的。此外,除非可选参数 debug 设置为 true,否则结果要么是值,要么是未定义。

          const axios = require('axios');
          
          // replace these URLs with whatever is good for you
          const remoteIPv4Url = 'http://ipv4bot.whatismyipaddress.com/';
          const remoteIPv6Url = 'http://ipv6bot.whatismyipaddress.com/';
          
          // Try getting an external IPv4 address.
          async function getExternalIPv4(debug = false) {
            try {
              const response = await axios.get(remoteIPv4Url);
              if (response && response.data) {
                return response.data;
              }
            } catch (error) {
              if (debug) {
                console.log(error);
              }
            }
            return undefined;
          }
          
          // Try getting an external IPv6 address.
          async function getExternalIPv6(debug = false) {
            try {
              const response = await axios.get(remoteIPv6Url);
              if (response && response.data) {
                return response.data;
              }
            } catch (error) {
              if (debug) {
                console.log(error);
              }
            }
            return undefined;
          }
          
          async function getExternalIP(debug = false) {
            let address;
            // Try IPv6 and then IPv4
            address = await getExternalIPv6(debug);
            if (!address) {
              address = await getExternalIPv4(debug);
            }
            return address;
          }
          
          module.exports { getExternalIP, getExternalIPv4, getExternalIPv6 }
          

          欢迎提出改进建议。

          【讨论】:

            【解决方案10】:

            我的无耻插件:canihazip披露:我是模块的作者,但不是主页的作者。

            它可以作为一个模块被要求,公开一个函数,可以选择传递一个回调函数,它会返回一个承诺。

            它也可以全局安装并用作CLI。

            【讨论】:

              【解决方案11】:

              您可以非常轻松地使用 api 解决方案来检索外部 IP! 几天前,我为这种事情制作了一个 ip 跟踪器网站! 这是您可以用来获取 IP 的代码片段!

              async function getIp(cb) {
                  let output = null;
                  let promise = new Promise(resolve => {
                      let http = new XMLHttpRequest();
                      http.onreadystatechange = function() {
                          if (this.readyState == 4 && this.status == 200) {
                              output = this.responseText;
                              resolve("done");
                          }
                      }
                      http.open("GET", "https://iptrackerz.herokuapp.com/ip", true);
                      http.send();
                 });
                await promise;
                if (cb != undefined) {
                    cb(JSON.parse(output)["ip"]);
                } else {
                    return JSON.parse(output)["ip"];
                }
              }
              

              好的,现在你有了getIp()函数! 我编写它的方式允许您执行 2 种不同的调用方式! 他们来了。

              1. 异步

                异步函数 printIP() { 让 ip = 等待 getIp(); document.write("你的IP是" + ip); }; 打印IP();

              2. 回调

                getIp(ip => { document.write("你的IP是" + ip); });

              【讨论】:

                【解决方案12】:

                我正在寻找一种不依赖于其他库/资源的解决方案, 并发现这是可接受的替代方案:

                只是对外部服务器的 GET 请求(在我的控制下), 我在这里阅读 req.headers['x-forwarded-for'] 并将其返回给我的客户。

                【讨论】:

                  【解决方案13】:

                  node.js 有很多很棒的内置模块,您可以在不包含任何外部依赖项的情况下使用。你可以制作这个文件。
                  WhatsMyIpAddress.js

                  const http = require('http');
                  
                  function WhatsMyIpAddress(callback) {
                      const options = {
                          host: 'ipv4bot.whatismyipaddress.com',
                          port: 80,
                          path: '/'
                      };
                      http.get(options, res => {
                          res.setEncoding('utf8');
                          res.on("data", chunk => callback(chunk, null));
                      }).on('error', err => callback(null, err.message));
                  }
                  
                  module.exports = WhatsMyIpAddress;
                  

                  然后像这样在你的 main.js 中调用它。

                  ma​​in.js

                  const WhatsMyIpAddress = require('./src/WhatsMyIpAddress');
                  WhatsMyIpAddress((data,err) => {
                     console.log('results:', data, err);
                  });
                  

                  【讨论】:

                    【解决方案14】:

                    您可以使用nurl 库命令ippublic 来获取此信息。 (披露:我做了nurl)

                    > npm install nurl-cli -g
                    > ippublic;
                    // 50.240.33.6
                    

                    【讨论】:

                      猜你喜欢
                      • 1970-01-01
                      • 2021-11-20
                      • 2013-04-03
                      • 2016-03-10
                      • 1970-01-01
                      • 2017-01-26
                      • 2013-08-04
                      • 2011-03-16
                      相关资源
                      最近更新 更多