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


Answers

更新 :我一直想制作一个最小/最大的代码版本,所以这里是一个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。

我在哪里从 - > Source

Question

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

我并不反对使用免费的第三方脚本。




您可以使用我的服务http://ipinfo.io来获得这个服务,这会为您提供客户IP,主机名,地理位置信息和网络所有者。 以下是一个记录IP的简单示例:

$.get("http://ipinfo.io", function(response) {
    console.log(response.ip);
}, "jsonp");

下面是一个更详细的JSFiddle示例,它还打印出完整的响应信息,以便您可以看到所有可用的详细信息: http://jsfiddle.net/zK5FN/2/ : http://jsfiddle.net/zK5FN/2/




我会说乍得和马耳他有很好的答案。 但是,他们很复杂。 所以我建议我从国家插件的广告中找到这个代码

<script>
<script language="javascript" src="http://j.maxmind.com/app/geoip.js"></script>
<script language="javascript">
mmjsCountryCode = geoip_country_code();
mmjsCountryName = geoip_country_name();

</script>

没有ajax。 只是简单的JavaScript。 :d

如果你去http://j.maxmind.com/app/geoip.js你会看到它包含

function geoip_country_code() { return 'ID'; }
function geoip_country_name() { return 'Indonesia'; }
function geoip_city()         { return 'Jakarta'; }
function geoip_region()       { return '04'; }
function geoip_region_name()  { return 'Jakarta Raya'; }
function geoip_latitude()     { return '-6.1744'; }
function geoip_longitude()    { return '106.8294'; }
function geoip_postal_code()  { return ''; }
function geoip_area_code()    { return ''; }
function geoip_metro_code()   { return ''; }

它并没有真正回答这个问题,因为

http://j.maxmind.com/app/geoip.js不包含IP(尽管我敢打赌它使用IP来获取国家)。

但是制作一个类似Pop的PhP脚本非常容易

function visitorsIP()   { return '123.123.123.123'; }

做到这一点。 穿上http://yourdomain.com/yourip.php

然后做

<script language="javascript" src="http://yourdomain.com/yourip.php"></script>

这个问题特别提到不使用第三方脚本。 没有其他办法。 Javascript无法知道你的IP。 但是其他可以通过javascript访问的服务器可以正常工作,而且没有问题。




没有真正可靠的方法来获取客户端计算机的IP地址。

这经历了一些可能性。 如果用户有多个接口,则使用Java的代码将会中断。

http://nanoagent.blogspot.com/2006/09/how-to-find-evaluate-remoteaddrclients.html

从这里查看其他答案,听起来您可能想要获取客户端的公共IP地址,这可能是他们用来连接到互联网的路由器的地址。 这里有很多其他答案都是这样说的。 我建议创建并托管自己的服务器端页面,以接收请求并使用IP地址进行响应,而不是依赖于别人的服务可能会或可能不会继续工作。




好吧,我从这个问题上离题,但今天我有类似的需求,虽然我无法从使用Javascript的客户端中找到ID,但我做了以下操作。

在服务器端: -

<div style="display:none;visibility:hidden" id="uip"><%= Request.UserHostAddress %></div>

使用Javascript

var ip = $get("uip").innerHTML;

我使用ASP.Net Ajax,但可以使用getElementById而不是$ get()。

发生的是,我在页面上有一个隐藏的div元素,用户的IP从服务器上呈现。 比在Javascript中,我只是加载该值。

这可能对一些与你类似的需求的人有帮助(像我一样,但我没有弄清楚)。

干杯!




<!DOCTYPE html>
<html ng-app="getIp">
<body>
    <div ng-controller="getIpCtrl">
        <div ng-bind="ip"></div>
    </div>

    <!-- Javascript for load faster
    ================================================== -->
    <script src="lib/jquery/jquery.js"></script>
    <script src="lib/angular/angular.min.js"></script>
    <script>
    /// Scripts app

    'use strict';

    /* App Module */
    var getIp = angular.module('getIp', [ ]);

    getIp.controller('getIpCtrl', ['$scope', '$http',
      function($scope, $http) {
        $http.jsonp('http://jsonip.appspot.com/?callback=JSON_CALLBACK')
            .success(function(data) {
            $scope.ip = data.ip;
        });
      }]);

    </script>
</body>
</html>



I'm going to offer a method that I use a lot when I want to store information in the html page, and want my javascript to read information without actually having to pass parameters to the javascript. This is especially useful when your script is referenced externally, rather than inline.

It doesn't meet the criterion of "no server side script", however. But if you can include server side scripting in your html, do this:

Make hidden label elements at the bottom of your html page, just above the end body tag.

Your label will look like this:

<label id="ip" class="hiddenlabel"><?php echo $_SERVER['REMOTE_ADDR']; ?></label>

Be sure to make a class called hiddenlabel and set the visibility:hidden so no one actually sees the label. You can store lots of things this way, in hidden labels.

Now, in your javascript, to retrieve the information stored in the label (in this case the client's ip address), you can do this:

var ip = document.getElementById("ip").innerHTML;

Now your variable "ip" equals the ip address. Now you can pass the ip to your API request.

* EDIT 2 YEARS LATER * Two minor refinements:

I routinely use this method, but call the label class="data" , because, in fact, it is a way to store data. Class name "hiddenlabel" is kind of a stupid name.

The second modification is in the style sheet, instead of visibility:hidden :

.data{
    display:none;
}

...is the better way of doing it.




Use ipdata.co .

The API also provides geolocation data and has 10 global endpoints each able to handle >800M requests a day!

$.get("https://api.ipdata.co", function (response) {
    $("#response").html(response.ip);
}, "jsonp");
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<pre id="response"></pre>




使用Smart-IP.net Geo-IP API 。 例如,通过使用jQuery:

$(document).ready( function() {
    $.getJSON( "http://smart-ip.net/geoip-json?callback=?",
        function(data){
            alert( data.host);
        }
    );
});



You can use web services like: http://ip-api.com/

例:

<script type="text/javascript" src="http://ip-api.com/json/?callback=foo">
<script>
    function foo(json) {
        alert(json.query)
    }
</script>

additional example: http://whatmyip.info    



这里的大多数答案都是通过......击中其他人的服务器来“解决”服务器端代码的需求。 这是一个完全有效的技术,除非你确实需要在不碰到服务器的情况下获取IP地址。

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

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







你不能。 你必须问一个服务器。




试试JAvascript

$.getJSON("http://smart-ip.net/geoip-json?callback=?", function(data){
   alert(data.host);
});

要么

http://jsfiddle.net/ourcodeworld/cks0v68q/?utm_source=website&utm_medium=embed&utm_campaign=cks0v68q




Appspot.com callback's service isn't available. ipinfo.io seems to be working.

I did an extra step and retrieved all geo info using AngularJS. (Thanks to Ricardo) Check it out.

<div ng-controller="geoCtrl">
  <p ng-bind="ip"></p>
  <p ng-bind="hostname"></p>
  <p ng-bind="loc"></p>
  <p ng-bind="org"></p>
  <p ng-bind="city"></p>
  <p ng-bind="region"></p>
  <p ng-bind="country"></p>
  <p ng-bind="phone"></p>
</div>
<script src="http://code.jquery.com/jquery-1.10.2.min.js"></script>
<script src="http://code.angularjs.org/1.2.12/angular.min.js"></script>
<script src="http://code.angularjs.org/1.2.12/angular-route.min.js"></script>
<script>
'use strict';
var geo = angular.module('geo', [])
.controller('geoCtrl', ['$scope', '$http', function($scope, $http) {
  $http.jsonp('http://ipinfo.io/?callback=JSON_CALLBACK')
    .success(function(data) {
    $scope.ip = data.ip;
    $scope.hostname = data.hostname;
    $scope.loc = data.loc; //Latitude and Longitude
    $scope.org = data.org; //organization
    $scope.city = data.city;
    $scope.region = data.region; //state
    $scope.country = data.country;
    $scope.phone = data.phone; //city area code
  });
}]);
</script>

Working page here: http://www.orangecountyseomarketing.com/projects/_ip_angularjs.html




Links