如何使用 JavaScript 获取客户端的 IP 地址?

IT技术 javascript jquery ip-address
2021-02-05 19:17:45

我需要使用 JavaScript 以某种方式检索客户端的 IP 地址;没有服务器端代码,甚至没有 SSI。

但是,我不反对使用免费的 3rd 方脚本/服务。

6个回答

我将使用可以返回 JSON 的 Web 服务(与 jQuery 一起使事情更简单)。以下是我可以找到的所有活动的免费 IP 查找服务以及它们返回的信息。如果您知道其他人,请添加评论,我会更新此答案。


抽象的

let apiKey = '1be9a6884abd4c3ea143b59ca317c6b2';
$.getJSON('https://ipgeolocation.abstractapi.com/v1/?api_key=' + apiKey, function(data) {
  console.log(JSON.stringify(data, null, 2));
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>

限制:

  • 每月 10,000 个请求
  • 需要注册才能获取您的 API 密钥

大数据云

// Base
let apiKey = 'd9e53816d07345139c58d0ea733e3870';
$.getJSON('https://api.bigdatacloud.net/data/ip-geolocation?key=' + apiKey, function(data) {
  console.log(JSON.stringify(data, null, 2));
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>

// Base + Confidence Area
let apiKey = 'd9e53816d07345139c58d0ea733e3870';
$.getJSON('https://api.bigdatacloud.net/data/ip-geolocation-with-confidence?key=' + apiKey, function(data) {
  console.log(JSON.stringify(data, null, 2));
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>

// Base + Confidence Area + Hazard Report
let apiKey = 'd9e53816d07345139c58d0ea733e3870';
$.getJSON('https://api.bigdatacloud.net/data/ip-geolocation-full?key=' + apiKey, function(data) {
  console.log(JSON.stringify(data, null, 2));
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>

限制:

  • 每月 10,000 个请求
  • 需要注册才能获取您的 API 密钥

云耀斑

$.get('https://www.cloudflare.com/cdn-cgi/trace', function(data) {
  // Convert key-value pairs to JSON
  // https://stackoverflow.com/a/39284735/452587
  data = data.trim().split('\n').reduce(function(obj, pair) {
    pair = pair.split('=');
    return obj[pair[0]] = pair[1], obj;
  }, {});
  console.log(data);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>

限制:

  • 返回纯文本
  • 如果有,则仅返回 IPv6 地址

数据库IP

试试看: https : //api.db-ip.com/v2/free/self

$.getJSON('https://api.db-ip.com/v2/free/self', function(data) {
  console.log(JSON.stringify(data, null, 2));
});

返回:

{
  "ipAddress": "116.12.250.1",
  "continentCode": "AS",
  "continentName": "Asia",
  "countryCode": "SG",
  "countryName": "Singapore",
  "city": "Singapore (Queenstown Estate)"
}

限制:

  • 每天 1,000 个请求
  • 需要非空的Origin请求头

地理字节

试试看: http : //gd.geobytes.com/GetCityDetails

$.getJSON('http://gd.geobytes.com/GetCityDetails?callback=?', function(data) {
  console.log(JSON.stringify(data, null, 2));
});

返回:

{
  "geobytesforwarderfor": "",
  "geobytesremoteip": "116.12.250.1",
  "geobytesipaddress": "116.12.250.1",
  "geobytescertainty": "99",
  "geobytesinternet": "SA",
  "geobytescountry": "Saudi Arabia",
  "geobytesregionlocationcode": "SASH",
  "geobytesregion": "Ash Sharqiyah",
  "geobytescode": "SH",
  "geobyteslocationcode": "SASHJUBA",
  "geobytescity": "Jubail",
  "geobytescityid": "13793",
  "geobytesfqcn": "Jubail, SH, Saudi Arabia",
  "geobyteslatitude": "27.004999",
  "geobyteslongitude": "49.660999",
  "geobytescapital": "Riyadh ",
  "geobytestimezone": "+03:00",
  "geobytesnationalitysingular": "Saudi Arabian ",
  "geobytespopulation": "22757092",
  "geobytesnationalityplural": "Saudis",
  "geobytesmapreference": "Middle East ",
  "geobytescurrency": "Saudi Riyal",
  "geobytescurrencycode": "SAR",
  "geobytestitle": "Saudi Arabia"
}

限制:

  • 每小时 16,384 次请求
  • 免费计划没有 SSL (https)
  • 可以返回错误的位置

GeoIPLookup.io

$.getJSON('https://json.geoiplookup.io/?callback=?', function(data) {
  console.log(JSON.stringify(data, null, 2));
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>

限制:

  • 每小时 10,000 个请求
  • 免费计划仅供非商业用途
  • 如果有,则仅返回 IPv6 地址

地理插件

试试看: http : //www.geoplugin.net/json.gp

$.getJSON('http://www.geoplugin.net/json.gp', function(data) {
  console.log(JSON.stringify(data, null, 2));
});

返回:

{
  "geoplugin_request": "116.12.250.1",
  "geoplugin_status": 200,
  "geoplugin_credit": "Some of the returned data includes GeoLite data created by MaxMind, available from <a href=\\'http://www.maxmind.com\\'>http://www.maxmind.com</a>.",
  "geoplugin_city": "Singapore",
  "geoplugin_region": "Singapore (general)",
  "geoplugin_areaCode": "0",
  "geoplugin_dmaCode": "0",
  "geoplugin_countryCode": "SG",
  "geoplugin_countryName": "Singapore",
  "geoplugin_continentCode": "AS",
  "geoplugin_latitude": "1.2931",
  "geoplugin_longitude": "103.855797",
  "geoplugin_regionCode": "00",
  "geoplugin_regionName": "Singapore (general)",
  "geoplugin_currencyCode": "SGD",
  "geoplugin_currencySymbol": "&#36;",
  "geoplugin_currencySymbol_UTF8": "$",
  "geoplugin_currencyConverter": 1.4239
}

限制:

  • 每分钟 120 个请求
  • 免费计划没有 SSL (https)

黑客目标

$.get('https://api.hackertarget.com/geoip/?q=116.12.250.1', function(data) {
  // Convert key-value pairs to JSON
  // https://stackoverflow.com/a/39284735/452587
  data = data.trim().split('\n').reduce(function(obj, pair) {
    pair = pair.split(': ');
    return obj[pair[0]] = pair[1], obj;
  }, {});
  console.log(data);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>

限制:

  • 每天 100 个请求
  • 需要 IP 地址参数
  • 返回纯文本

伊皮皮

试试看: https : //ipapi.co/json/

$.getJSON('https://ipapi.co/json/', function(data) {
  console.log(JSON.stringify(data, null, 2));
});

返回:

{
  "ip": "116.12.250.1",
  "city": "Singapore",
  "region": "Central Singapore Community Development Council",
  "country": "SG",
  "country_name": "Singapore",
  "postal": null,
  "latitude": 1.2855,
  "longitude": 103.8565,
  "timezone": "Asia/Singapore"
}

限制:

  • 每天 1,000 个请求
  • 需要 SSL (https)
  • 需要非空的Origin请求头
  • 如果有,则仅返回 IPv6 地址

应用程序接口

试试看: http : //ip-api.com/json

$.getJSON('http://ip-api.com/json', function(data) {
  console.log(JSON.stringify(data, null, 2));
});

返回:

{
  "as": "AS3758 SingNet",
  "city": "Singapore",
  "country": "Singapore",
  "countryCode": "SG",
  "isp": "SingNet Pte Ltd",
  "lat": 1.2931,
  "lon": 103.8558,
  "org": "Singapore Telecommunications",
  "query": "116.12.250.1",
  "region": "01",
  "regionName": "Central Singapore Community Development Council",
  "status": "success",
  "timezone": "Asia/Singapore",
  "zip": ""
}

限制:

  • 每分钟 150 个请求
  • 免费计划没有 SSL (https)

数据

let apiKey = 'be0f755b93290b4c100445d77533d291763a417c75524e95e07819ad';
$.getJSON('https://api.ipdata.co?api-key=' + apiKey, function(data) {
  console.log(JSON.stringify(data, null, 2));
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>

限制:

  • 每天 1,500 个请求
  • 需要注册才能获取您的 API 密钥
  • 需要 SSL (https)

IP查找

let apiKey = '50e887ce-e3bb-4f00-a9b9-667597db5539';
$.getJSON('https://ipfind.co/me?auth=' + apiKey, function(data) {
  console.log(JSON.stringify(data, null, 2));
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>

限制:

  • 每天 300 个请求
  • 需要注册才能获取您的 API 密钥

地理定位

let apiKey = 'f8e0b361e8f4405c94613ab534959fdf';
$.getJSON('https://api.ipgeolocation.io/ipgeo?apiKey=' + apiKey, function(data) {
  console.log(JSON.stringify(data, null, 2));
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>

限制:

  • 每月 50,000 个请求
  • 需要注册才能获取您的 API 密钥
  • 如果有,则仅返回 IPv6 地址

ipify

$.getJSON('https://api.ipify.org?format=jsonp&callback=?', function(data) {
  console.log(JSON.stringify(data, null, 2));
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>

限制:

  • 没有任何

信息数据库

let apiKey = '25864308b6a77fd90f8bf04b3021a48c1f2fb302a676dd3809054bc1b07f5b42';
$.getJSON('https://api.ipinfodb.com/v3/ip-city/?format=json&key=' + apiKey, function(data) {
  console.log(JSON.stringify(data, null, 2));
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>

限制:

  • 每秒两个请求
  • 需要注册才能获取您的 API 密钥

ipinfo.io

$.getJSON('https://ipinfo.io/json', function(data) {
  console.log(JSON.stringify(data, null, 2));
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>

限制:

  • 每月 50,000 个请求

知识产权

$.getJSON('https://api.ipregistry.co/?key=tryout', function(data) {
  console.log(JSON.stringify(data, null, 2));
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>

限制:

  • 免费计划包括 100,000 个请求
  • 需要注册才能获取您的 API 密钥
  • 如果有,则仅返回 IPv6 地址

ipstack(以前的 freegeoip.net)

试试看: http : //api.ipstack.com/ <ip_address> ?access_key= <your_api_key>

$.getJSON('http://api.ipstack.com/<ip_address>?access_key=<your_api_key>', function(data) {
  console.log(JSON.stringify(data, null, 2));
});

返回:

{
  "ip": "116.12.250.1",
  "type": "ipv4",
  "continent_code": "AS",
  "continent_name": "Asia",
  "country_code": "SG",
  "country_name": "Singapore",
  "region_code": "01",
  "region_name": "Central Singapore Community Development Council",
  "city": "Singapore",
  "zip": null,
  "latitude": 1.2931,
  "longitude": 103.8558,
  "location": {
    "geoname_id": 1880252,
    "capital": "Singapore",
    "languages": [
      {
        "code": "en",
        "name": "English",
        "native": "English"
      },
      {
        "code": "ms",
        "name": "Malay",
        "native": "Bahasa Melayu"
      },
      {
        "code": "ta",
        "name": "Tamil",
        "native": "தமிழ்"
      },
      {
        "code": "zh",
        "name": "Chinese",
        "native": "中文"
      }
    ],
    "country_flag": "http://assets.ipstack.com/flags/sg.svg",
    "country_flag_emoji": "🇸🇬",
    "country_flag_emoji_unicode": "U+1F1F8 U+1F1EC",
    "calling_code": "65",
    "is_eu": false
  }
}

限制:

  • 每月 10,000 个请求
  • 需要 IP 地址参数
  • 需要注册才能获取您的 API 密钥
  • 免费计划没有 SSL (https)

jsonip.com

$.getJSON('https://jsonip.com/', function(data) {
  console.log(JSON.stringify(data, null, 2));
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>

限制:

  • 如果有,则仅返回 IPv6 地址

JSON 测试

试试看: http : //ip.jsontest.com/

$.getJSON('http://ip.jsontest.com/', function(data) {
  console.log(JSON.stringify(data, null, 2));
});

返回:

{
  "ip": "116.12.250.1"
}

限制:

  • 无 SSL (https)
  • 如果有,则仅返回 IPv6 地址

史努比

let apiKey = 'ed5ebbeba257b8f262a6a9bbc0ec678e';
$.getJSON('https://api.snoopi.io/116.12.250.1?apikey=' + apiKey, function(data) {
  console.log(JSON.stringify(data, null, 2));
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>

限制:

  • 每月 10,000 个请求
  • 每 2 秒 1 个请求
  • 需要 IP 地址参数
  • 需要注册才能获取您的 API 密钥

香草 JAVASCRIPT

使用现代浏览器,您可以使用本机Fetch API而不是依赖 jQuery 的$.getJSON(). 下面是一个例子:

let apiKey = '1be9a6884abd4c3ea143b59ca317c6b2';
// Make the request
fetch('https://ipgeolocation.abstractapi.com/v1/?api_key=' + apiKey)
  // Extract JSON body content from HTTP response
  .then(response => response.json())
  // Do something with the JSON data
  .then(data => {
    console.log(JSON.stringify(data, null, 2))
  });

笔记

  • 由于这些都是免费服务,谁知道他们何时/是否会在未来下线(图 A:Telize)。
  • 如果您想要更多功能和稳定性,这些服务中的大多数还提供付费层。
  • 正如@skobaljic 在下面的评论中指出的那样,请求配额主要是学术性的,因为调用发生在客户端,并且大多数最终用户永远不会超过他们的配额。
  • 某些服务没有可运行的代码段,因为它们在免费计划中不允许 SSL 连接或需要非空Origin请求标头(StackOverflow 代码段被迫使用 https 并Origin: null在请求标头中包含)。

更新

2021 年更新:

正如最近一个新的 Github 存储库webrtc-ip 所示,您现在可以使用 WebRTC泄漏用户的公共IP 地址。可悲的是,由于逐渐转向 mDNS(至少对于 WebRTC),此泄漏不适用于私有 IP,在此处完全解释但是,这是一个有效的演示:

getIPs().then(res => document.write(res.join('\n')))
<script src="https://cdn.jsdelivr.net/gh/joeymalvinni/webrtc-ip/dist/bundle.dev.js"></script>

可以在此处找到此存储库的已编译源代码




(以前)最终更新

此解决方案将不再有效,因为浏览器正在修复 webrtc 泄漏:有关该问题的更多信息,请阅读另一个问题:RTCIceCandidate 不再返回 IP


更新:我一直想制作一个最小/丑化版本的代码,所以这里是一个 ES6 Promise 代码:

var findIP = new Promise(r=>{var w=window,a=new (w.RTCPeerConnection||w.mozRTCPeerConnection||w.webkitRTCPeerConnection)({iceServers:[]}),b=()=>{};a.createDataChannel("");a.createOffer(c=>a.setLocalDescription(c,b,b),b);a.onicecandidate=c=>{try{c.candidate.candidate.match(/([0-9]{1,3}(\.[0-9]{1,3}){3}|[a-f0-9]{1,4}(:[a-f0-9]{1,4}){7})/g).forEach(r)}catch(e){}}})

/*Usage example*/
findIP.then(ip => document.write('your ip: ', ip)).catch(e => console.error(e))

注意:如果您想要用户的所有 IP(可能更多取决于他的网络),则此新的缩小代码将仅返回单个 IP,请使用原始代码...


感谢WebRTC,在支持 WebRTC 的浏览器中获取本地 IP 非常容易(至少现在是这样)。我修改了源代码,减少了行数,没有提出任何令人震惊的请求,因为您只需要本地 IP,而不是公共 IP,以下代码适用于最新的 Firefox 和 Chrome,只需运行代码段并自行检查:

function findIP(onNewIP) { //  onNewIp - your listener function for new IPs
  var myPeerConnection = window.RTCPeerConnection || window.mozRTCPeerConnection || window.webkitRTCPeerConnection; //compatibility for firefox and chrome
  var pc = new myPeerConnection({iceServers: []}),
    noop = function() {},
    localIPs = {},
    ipRegex = /([0-9]{1,3}(\.[0-9]{1,3}){3}|[a-f0-9]{1,4}(:[a-f0-9]{1,4}){7})/g,
    key;

  function ipIterate(ip) {
    if (!localIPs[ip]) onNewIP(ip);
    localIPs[ip] = true;
  }
  pc.createDataChannel(""); //create a bogus data channel
  pc.createOffer(function(sdp) {
    sdp.sdp.split('\n').forEach(function(line) {
      if (line.indexOf('candidate') < 0) return;
      line.match(ipRegex).forEach(ipIterate);
    });
    pc.setLocalDescription(sdp, noop, noop);
  }, noop); // create offer and set local description
  pc.onicecandidate = function(ice) { //listen for candidate events
    if (!ice || !ice.candidate || !ice.candidate.candidate || !ice.candidate.candidate.match(ipRegex)) return;
    ice.candidate.candidate.match(ipRegex).forEach(ipIterate);
  };
}



var ul = document.createElement('ul');
ul.textContent = 'Your IPs are: '
document.body.appendChild(ul);

function addIP(ip) {
  console.log('got ip: ', ip);
  var li = document.createElement('li');
  li.textContent = ip;
  ul.appendChild(li);
}

findIP(addIP);
<h1> Demo retrieving Client IP using WebRTC </h1>

这里发生的事情是,我们正在创建一个虚拟的对等连接,并且为了让远程对等与我们联系,我们通常会相互交换冰候选。并读取冰候选(从本地会话描述和 onIceCandidateEvent)我们可以知道用户的 IP。

我从哪里获取代码 -->源代码

@FloatingRock 您也可以使用 STUN 服务器检索公共 IP(并在创建对等方时配置它),然后再次,这将需要您维护/使用 STUN 服务器,将服务器代码带入图片。
2021-03-12 19:17:45
@BeniBela 更新了代码以使用 firefox 26,在 windows 机器上签入,你能检查并确认吗?
2021-03-20 19:17:45
警告:这不会显示您的公共 IP,仅显示本地网络 IP。你不能用它来检测用户国家,例如,如果他们在局域网上
2021-03-22 19:17:45
我在 Firefox 26 中收到“错误:RTCPeerConnection 构造函数传递了无效的 RTCConfiguration - 格式错误的 URI:未定义”
2021-03-25 19:17:45
这被称为 WebRTC 泄漏。应该由所有市长浏览器修复,但事实并非如此。更多信息请访问:privacytools.io/webrtc.html可能与 Tor 浏览器泄露您的真实 IP 相关。
2021-03-26 19:17:45

你可以,通过服务器端使用 JSONP 中继它

在谷歌上搜索时,在此处找到了 SO Can I perform a DNS lookup (hostname to IP address) using client-side Javascript?

<script type="application/javascript">
    function getip(json){
      alert(json.ip); // alerts the ip address
    }
</script>

<script type="application/javascript" src="http://www.telize.com/jsonip?callback=getip"></script>

注意: telize.com API 已于2015 年 11 月 15 日永久关闭

这不是一个好的答案,因为它涉及服务器端请求。该问题明确指出“纯javascript”。
2021-03-14 19:17:45
该服务现已关闭。
2021-03-15 19:17:45
Micah,使用纯javascript无法获得IP地址。我建议您阅读有关 NAT 及其工作原理的内容。您需要一台服务器将您的互联网 IP 地址回传给您
2021-03-25 19:17:45
虽然我很欣赏这个片段,但我认为加载 JavaScript 文本内容并通过函数评估它是一个严重的安全风险。如果响应的内容发生变化,并且这里所有 100 多人投票支持该答案并可能使用该代码段最终调用具有可能不安全内容的函数,该怎么办?如果它是一个 JSON 字符串,我只会使用它。
2021-04-01 19:17:45
Error Over Quota This application is temporarily over its serving quota. Please try again later.
2021-04-04 19:17:45

这里的大多数答案“解决”了对服务器端代码的需求... 这是一种完全有效的技术,除非您确实需要在不访问服务器的情况下获取 IP 地址。

传统上,如果没有某种插件,这是不可能的(即使那样,如果您在 NAT 路由器后面,您可能会得到错误的IP 地址),但是随着 WebRTC 的出现,实际上可以做到这一点.. .如果您的目标浏览器支持 WebRTC(目前:Firefox、Chrome 和 Opera)。

有关如何使用 WebRTC 检索有用的客户端 IP 地址的详细信息,请阅读 mido 的回答

根据那个“CanIUse”链接,它是@BugWhisperer。除非你需要IE。
2021-03-09 19:17:45
由于 WebRTC,此答案已过时:stackoverflow.com/questions/20194722/...
2021-03-19 19:17:45
更新,@Akam。几个月前,您应该给 mido 一些提示以指出这一点(在许多人发布仍然需要服务器支持的令人尴尬的错误答案之后)。
2021-03-20 19:17:45
WebRTC 现在得到更广泛的支持了吗?!
2021-04-06 19:17:45
@oscar:这似乎与乍得在他的回答中提到的技术(JSONP 返回的服务器可见 IP)相同。这与 OP 的“无服务器端代码”要求不符。但是,是的,如果您忽略该要求,这是实现它的一种方法。
2021-04-08 19:17:45

你不能。你得问服务员。

但它有点,对吧?我的意思是,如果答案只是“不,你不能”,那么我会争辩说这是一个比当前投票的“在这里,使用这个随机的应用程序”更正确的答案,这似乎是一个危险的答案榜首。
2021-03-26 19:17:45
@matthewwithanm 我完全同意。我正在浏览所有答案,看看是否有人准确地说了这一点 - 并准备自己提供它作为答案。所有高度赞成的答案虽然信息丰富,但都回答了不同的问题。引用这个问题:“我需要使用纯 JavaScript 以某种方式提取客户端的 IP 地址;没有服务器端代码,甚至没有 SSI。” 事实上,这个答案是正确的答案。浏览器沙盒 Javascript 无法做到这一点(无论 NAT 或代理如何)。如果要接受其他答案之一,则应更改问题。
2021-03-26 19:17:45
IMO 这是正确的答案,应该被接受。该问题明确指出“没有服务器端代码”。
2021-03-28 19:17:45
这并没有提供问题的答案。要批评或要求作者澄清,请在他们的帖子下方发表评论。
2021-04-06 19:17:45