我可以使用客户端Javascript执行DNS查询(主机名到IP地址)吗?

时间:2022-03-01 16:59:05

I would like to use client-side Javascript to perform a DNS lookup (hostname to IP address) as seen from the client's computer. Is that possible?

我希望使用客户端Javascript执行从客户端计算机看到的DNS查找(主机名到IP地址)。这有可能吗?

12 个解决方案

#1


28  

There's no notion of hosts or ip-addresses in the javascript standard library. So you'll have to access some external service to look up hostnames for you.

在javascript标准库中没有主机或ip地址的概念。因此,您必须访问一些外部服务,以便为您查找主机名。

I recommend hosting a cgi-bin which looks up the ip-address of a hostname and access that via javascript.

我建议托管一个cgi-bin,它可以查找主机名的ip地址并通过javascript进行访问。

#2


90  

Edit: This question gave me an itch, so I put up a JSONP webservice on Google App Engine that returns the clients ip address. Usage:

编辑:这个问题让我很痒,所以我在谷歌应用程序引擎上安装了一个JSONP webservice,它返回客户端ip地址。用法:

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

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

Yay, no server proxies needed.

是的,不需要服务器代理。


Pure JS can't. If you have a server script under the same domain that prints it out you could send a XMLHttpRequest to read it.

纯JS不能。如果在打印它的相同域中有一个服务器脚本,可以发送XMLHttpRequest来读取它。

#3


20  

Very late, but I guess many people will still land here through "Google Airlines". A moderm approach is to use WebRTC that doesn't require server support.

很晚了,但我猜很多人还是会通过谷歌航空公司降落。现代方法是使用不需要服务器支持的WebRTC。

https://hacking.ventures/local-ip-discovery-with-html5-webrtc-security-and-privacy-risk/

https://hacking.ventures/local-ip-discovery-with-html5-webrtc-security-and-privacy-risk/

Next code is a copy&paste from http://net.ipcalf.com/

下一个代码是来自http://net.ipcalf.com/的copy&paste

// NOTE: window.RTCPeerConnection is "not a constructor" in FF22/23
var RTCPeerConnection = /*window.RTCPeerConnection ||*/ window.webkitRTCPeerConnection || window.mozRTCPeerConnection;

if (RTCPeerConnection) (function () {
    var rtc = new RTCPeerConnection({iceServers:[]});
    if (window.mozRTCPeerConnection) {      // FF needs a channel/stream to proceed
        rtc.createDataChannel('', {reliable:false});
    };  

    rtc.onicecandidate = function (evt) {
        if (evt.candidate) grepSDP(evt.candidate.candidate);
    };  
    rtc.createOffer(function (offerDesc) {
        grepSDP(offerDesc.sdp);
        rtc.setLocalDescription(offerDesc);
    }, function (e) { console.warn("offer failed", e); }); 


    var addrs = Object.create(null);
    addrs["0.0.0.0"] = false;
    function updateDisplay(newAddr) {
        if (newAddr in addrs) return;
        else addrs[newAddr] = true;
        var displayAddrs = Object.keys(addrs).filter(function (k) { return addrs[k]; }); 
        document.getElementById('list').textContent = displayAddrs.join(" or perhaps ") || "n/a";
    }   

    function grepSDP(sdp) {
        var hosts = []; 
        sdp.split('\r\n').forEach(function (line) { // c.f. http://tools.ietf.org/html/rfc4566#page-39
            if (~line.indexOf("a=candidate")) {     // http://tools.ietf.org/html/rfc4566#section-5.13
                var parts = line.split(' '),        // http://tools.ietf.org/html/rfc5245#section-15.1
                    addr = parts[4],
                    type = parts[7];
                if (type === 'host') updateDisplay(addr);
            } else if (~line.indexOf("c=")) {       // http://tools.ietf.org/html/rfc4566#section-5.7
                var parts = line.split(' '), 
                    addr = parts[2];
                updateDisplay(addr);
            }   
        }); 
    }   
})(); else {
    document.getElementById('list').innerHTML = "<code>ifconfig | grep inet | grep -v inet6 | cut -d\" \" -f2 | tail -n1</code>";
    document.getElementById('list').nextSibling.textContent = "In Chrome and Firefox your IP should display automatically, by the power of WebRTCskull.";
}   

#4


13  

The hosted JSONP version works like a charm, but it seems it goes over its resources during night time most days (Eastern Time), so I had to create my own version.

托管的JSONP版本工作起来很有魅力,但它似乎在大多数时间(东部时间)的晚上都有它的资源,所以我必须创建自己的版本。

This is how I accomplished it with PHP:

这就是我用PHP实现的方法:

<?php
header('content-type: application/json; charset=utf-8');

$data = json_encode($_SERVER['REMOTE_ADDR']);
echo $_GET['callback'] . '(' . $data . ');';
?>

Then the Javascript is exactly the same as before, just not an array:

那么Javascript和之前完全一样,只是不是数组:

<script type="application/javascript">
function getip(ip){
    alert('IP Address: ' + ip);
}
</script>

<script type="application/javascript" src="http://www.anotherdomain.com/file.php?callback=getip"> </script>

Simple as that!

就这么简单!

Side note: Be sure to clean your $_GET if you're using this in any public-facing environment!

附加说明:如果您在任何面向公众的环境中使用$_GET,请务必清理您的$_GET !

#5


2  

I am aware this is an old question but my solution may assist others.

我知道这是一个老问题,但我的解决方案可能会对其他人有所帮助。

I find that the JSON(P) services which make this easy do not last forever but the following JavaScript works well for me at the time of writing.

我发现JSON(P)服务使这个过程变得简单,但它不会永远持续下去,但是下面的JavaScript在我写作的时候很适合我。

<script type="text/javascript">function z (x){ document.getElementById('y').innerHTML=x.query }</script>
<script type='text/javascript' src='http://ip-api.com/json/zero.eu.org?callback=z'></script>

The above writes my server's IP on the page it is located but the script can be modified to find any IP by changing 'zero.eu.org' to another domain name. This can be seen in action on my page at: http://meon.zero.eu.org/

上面的代码将我的服务器的IP写到它所在的页面上,但是可以通过将“zero.eu.org”更改为另一个域名来修改脚本以查找任何IP。这可以在我的页面上看到:http://meon.zero.eu.org/。

#6


2  

There's a third-party service which provides a CORS-friendly REST API to perform DNS lookups from the browser - https://exana.io/tools/dns/

有一个第三方服务,它提供了一个对内核友好的REST API来执行浏览器的DNS查询——https://exana.io/tools/dns/

#7


1  

As many people said you need to use an external service and call it. And that will only get you the DNS resolution from the server perspective.

正如许多人所说,您需要使用外部服务并调用它。这只能从服务器的角度得到DNS解析。

If that's good enough and if you just need DNS resolution you can use the following Docker container:

如果这足够好,如果你只需要DNS解析,你可以使用以下Docker容器:

https://github.com/kuralabs/docker-webaiodns

https://github.com/kuralabs/docker-webaiodns

Endpoints:

端点:

[GET] /ipv6/[domain]: Perform a DNS resolution for given domain and return the associated IPv6 addresses.

[GET] /ipv6/[domain]:为给定的域执行DNS解析并返回相关的ipv6地址。

 {
     "addresses": [
         "2a01:91ff::f03c:7e01:51bd:fe1f"
     ]
 }

[GET] /ipv4/[domain]: Perform a DNS resolution for given domain and return the associated IPv4 addresses.

[GET] /ipv4/[domain]:为给定的域执行DNS解析并返回相关联的ipv4地址。

 {
     "addresses": [
         "139.180.232.162"
     ]
 }

My recommendation is that you setup your web server to reverse proxy to the container on a particular endpoint in your server serving your Javascript and call it using your standard Javascript Ajax functions.

我的建议是,设置web服务器将代理反向到服务Javascript的服务器中的特定端点上的容器,并使用标准的Javascript Ajax函数调用它。

#8


0  

Doing this would require to break the browser sandbox. Try to let your server do the lookup and request that from the client side via XmlHttp.

这样做需要打破浏览器沙箱。尝试让服务器通过XmlHttp从客户端进行查找和请求。

#9


-1  

I don't think this is allowed by most browsers for security reasons, in a pure JavaScript context as the question asks.

出于安全考虑,我认为大多数浏览器都不允许这样做,在纯JavaScript环境中。

#10


-2  

My version is like this:

我的版本是这样的:

php on my server:

php在我的服务器:

<?php
    header('content-type: application/json; charset=utf-8');

    $data = json_encode($_SERVER['REMOTE_ADDR']);


    $callback = filter_input(INPUT_GET, 
                 'callback',
                 FILTER_SANITIZE_STRING, 
                 FILTER_FLAG_ENCODE_HIGH|FILTER_FLAG_ENCODE_LOW);
    echo $callback . '(' . $data . ');';
?>

jQuery on the page:

jQuery的页面:

var self = this;
$.ajax({
    url: this.url + "getip.php",
    data: null,
    type: 'GET',
    crossDomain: true,
    dataType: 'jsonp'

}).done( function( json ) {

    self.ip = json;

});

It works cross domain. It could use a status check. Working on that.

它是跨域。它可以使用状态检查。在那工作。

#11


-2  

Maybe I missed the point but in reply to NAVY guy here is how the browser can tell you the 'requestor's' IP address (albeit maybe only their service provider).

也许我错过了这一点,但在回答海军的问题时,浏览器可以告诉你“请求者”的IP地址(尽管可能只是他们的服务提供者)。

Place a script tag in the page to be rendered by the client that calls (has src pointing to) another server that is not loaded balanced (I realize that this means you need access to a 2nd server but hosting is cheap these days and you can set this up easily and cheaply).

放置一个脚本标签在页面呈现由客户机调用(src指着)另一个服务器不加载平衡(我知道这意味着您需要访问第二个服务器但托管这些天很便宜,你可以很容易实现和便宜)。

This is the kind of code that needs to be added to client page:

这是需要添加到客户端页面的代码:

On the other server "someServerIown" you need to have the ASP, ASPX or PHP page that;

在另一个服务器“someServerIown”上,需要有ASP、ASPX或PHP页面;

----- contains server code like this:

----包含如下服务器代码:

"<% Response.Write("var clientipaddress = '" & Request.ServerVariables("REMOTE_ADDR") & "';") %>" (without the outside dbl quotes :-))

“< %响应。写入(“var clientipaddress = '”和Request.ServerVariables(“REMOTE_ADDR”)和“;”)%>(没有外部dbl引号:-)

---- and writes this code back to script tag:

——将此代码写回脚本标签:

   var clientipaddress = '178.32.21.45';

This effectively creates a Javascript variable that you can access with Javascript on the page no less.

这有效地创建了一个Javascript变量,您可以在页面上使用Javascript进行访问。

Hopefully, you access this var and write the value to a form control ready for sending back.

希望您能够访问这个var并将值写入一个表单控件中,以便返回。

When the user posts or gets on the next request your Javascript and/or form sends the value of the variable that the "otherServerIown" has filled in for you, back to the server you would like it on.

当用户发布或获取下一个请求时,您的Javascript和/或表单将“otherServerIown”为您填充的变量的值发送回服务器。

This is how I get around the dumb load balancer we have that masks the client IP address and makes it appear as that of the Load balancer .... dumb ... dumb dumb dumb!

这就是我如何绕过我们愚蠢的负载均衡器面具客户机IP地址和使它出现的负载均衡器....愚蠢的…愚蠢的愚蠢的愚蠢!

I haven't given the exact solution because everyone's situation is a little different. The concept is sound, however. Also, note if you are doing this on an HTTPS page your "otherServerIOwn" must also deliver in that secure form otherwise Client is alerted to mixed content. And if you do have https then make sure ALL your certs are valid otherwise client also gets a warning.

我没有给出确切的答案,因为每个人的情况都有点不同。然而,这一概念是合理的。另外,请注意,如果您在HTTPS页面上执行此操作,那么您的“otherServerIOwn”也必须以该安全表单交付,否则客户端将被警告混合内容。如果您有https,那么请确保您的所有证书都是有效的,否则客户端也会收到警告。

Hope it helps someone! Sorry, it took a year to answer/contribute. :-)

希望它能帮助一些人!对不起,我花了一年的时间才回复/投稿。:-)

#12


-9  

If the client has Java installed, you could do something like this:

如果客户端安装了Java,您可以这样做:

ipAddress = java.net.InetAddress.getLocalHost().getHostAddress();

Other than that, you will probably have to use a server side script.

除此之外,您可能还需要使用服务器端脚本。

#1


28  

There's no notion of hosts or ip-addresses in the javascript standard library. So you'll have to access some external service to look up hostnames for you.

在javascript标准库中没有主机或ip地址的概念。因此,您必须访问一些外部服务,以便为您查找主机名。

I recommend hosting a cgi-bin which looks up the ip-address of a hostname and access that via javascript.

我建议托管一个cgi-bin,它可以查找主机名的ip地址并通过javascript进行访问。

#2


90  

Edit: This question gave me an itch, so I put up a JSONP webservice on Google App Engine that returns the clients ip address. Usage:

编辑:这个问题让我很痒,所以我在谷歌应用程序引擎上安装了一个JSONP webservice,它返回客户端ip地址。用法:

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

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

Yay, no server proxies needed.

是的,不需要服务器代理。


Pure JS can't. If you have a server script under the same domain that prints it out you could send a XMLHttpRequest to read it.

纯JS不能。如果在打印它的相同域中有一个服务器脚本,可以发送XMLHttpRequest来读取它。

#3


20  

Very late, but I guess many people will still land here through "Google Airlines". A moderm approach is to use WebRTC that doesn't require server support.

很晚了,但我猜很多人还是会通过谷歌航空公司降落。现代方法是使用不需要服务器支持的WebRTC。

https://hacking.ventures/local-ip-discovery-with-html5-webrtc-security-and-privacy-risk/

https://hacking.ventures/local-ip-discovery-with-html5-webrtc-security-and-privacy-risk/

Next code is a copy&paste from http://net.ipcalf.com/

下一个代码是来自http://net.ipcalf.com/的copy&paste

// NOTE: window.RTCPeerConnection is "not a constructor" in FF22/23
var RTCPeerConnection = /*window.RTCPeerConnection ||*/ window.webkitRTCPeerConnection || window.mozRTCPeerConnection;

if (RTCPeerConnection) (function () {
    var rtc = new RTCPeerConnection({iceServers:[]});
    if (window.mozRTCPeerConnection) {      // FF needs a channel/stream to proceed
        rtc.createDataChannel('', {reliable:false});
    };  

    rtc.onicecandidate = function (evt) {
        if (evt.candidate) grepSDP(evt.candidate.candidate);
    };  
    rtc.createOffer(function (offerDesc) {
        grepSDP(offerDesc.sdp);
        rtc.setLocalDescription(offerDesc);
    }, function (e) { console.warn("offer failed", e); }); 


    var addrs = Object.create(null);
    addrs["0.0.0.0"] = false;
    function updateDisplay(newAddr) {
        if (newAddr in addrs) return;
        else addrs[newAddr] = true;
        var displayAddrs = Object.keys(addrs).filter(function (k) { return addrs[k]; }); 
        document.getElementById('list').textContent = displayAddrs.join(" or perhaps ") || "n/a";
    }   

    function grepSDP(sdp) {
        var hosts = []; 
        sdp.split('\r\n').forEach(function (line) { // c.f. http://tools.ietf.org/html/rfc4566#page-39
            if (~line.indexOf("a=candidate")) {     // http://tools.ietf.org/html/rfc4566#section-5.13
                var parts = line.split(' '),        // http://tools.ietf.org/html/rfc5245#section-15.1
                    addr = parts[4],
                    type = parts[7];
                if (type === 'host') updateDisplay(addr);
            } else if (~line.indexOf("c=")) {       // http://tools.ietf.org/html/rfc4566#section-5.7
                var parts = line.split(' '), 
                    addr = parts[2];
                updateDisplay(addr);
            }   
        }); 
    }   
})(); else {
    document.getElementById('list').innerHTML = "<code>ifconfig | grep inet | grep -v inet6 | cut -d\" \" -f2 | tail -n1</code>";
    document.getElementById('list').nextSibling.textContent = "In Chrome and Firefox your IP should display automatically, by the power of WebRTCskull.";
}   

#4


13  

The hosted JSONP version works like a charm, but it seems it goes over its resources during night time most days (Eastern Time), so I had to create my own version.

托管的JSONP版本工作起来很有魅力,但它似乎在大多数时间(东部时间)的晚上都有它的资源,所以我必须创建自己的版本。

This is how I accomplished it with PHP:

这就是我用PHP实现的方法:

<?php
header('content-type: application/json; charset=utf-8');

$data = json_encode($_SERVER['REMOTE_ADDR']);
echo $_GET['callback'] . '(' . $data . ');';
?>

Then the Javascript is exactly the same as before, just not an array:

那么Javascript和之前完全一样,只是不是数组:

<script type="application/javascript">
function getip(ip){
    alert('IP Address: ' + ip);
}
</script>

<script type="application/javascript" src="http://www.anotherdomain.com/file.php?callback=getip"> </script>

Simple as that!

就这么简单!

Side note: Be sure to clean your $_GET if you're using this in any public-facing environment!

附加说明:如果您在任何面向公众的环境中使用$_GET,请务必清理您的$_GET !

#5


2  

I am aware this is an old question but my solution may assist others.

我知道这是一个老问题,但我的解决方案可能会对其他人有所帮助。

I find that the JSON(P) services which make this easy do not last forever but the following JavaScript works well for me at the time of writing.

我发现JSON(P)服务使这个过程变得简单,但它不会永远持续下去,但是下面的JavaScript在我写作的时候很适合我。

<script type="text/javascript">function z (x){ document.getElementById('y').innerHTML=x.query }</script>
<script type='text/javascript' src='http://ip-api.com/json/zero.eu.org?callback=z'></script>

The above writes my server's IP on the page it is located but the script can be modified to find any IP by changing 'zero.eu.org' to another domain name. This can be seen in action on my page at: http://meon.zero.eu.org/

上面的代码将我的服务器的IP写到它所在的页面上,但是可以通过将“zero.eu.org”更改为另一个域名来修改脚本以查找任何IP。这可以在我的页面上看到:http://meon.zero.eu.org/。

#6


2  

There's a third-party service which provides a CORS-friendly REST API to perform DNS lookups from the browser - https://exana.io/tools/dns/

有一个第三方服务,它提供了一个对内核友好的REST API来执行浏览器的DNS查询——https://exana.io/tools/dns/

#7


1  

As many people said you need to use an external service and call it. And that will only get you the DNS resolution from the server perspective.

正如许多人所说,您需要使用外部服务并调用它。这只能从服务器的角度得到DNS解析。

If that's good enough and if you just need DNS resolution you can use the following Docker container:

如果这足够好,如果你只需要DNS解析,你可以使用以下Docker容器:

https://github.com/kuralabs/docker-webaiodns

https://github.com/kuralabs/docker-webaiodns

Endpoints:

端点:

[GET] /ipv6/[domain]: Perform a DNS resolution for given domain and return the associated IPv6 addresses.

[GET] /ipv6/[domain]:为给定的域执行DNS解析并返回相关的ipv6地址。

 {
     "addresses": [
         "2a01:91ff::f03c:7e01:51bd:fe1f"
     ]
 }

[GET] /ipv4/[domain]: Perform a DNS resolution for given domain and return the associated IPv4 addresses.

[GET] /ipv4/[domain]:为给定的域执行DNS解析并返回相关联的ipv4地址。

 {
     "addresses": [
         "139.180.232.162"
     ]
 }

My recommendation is that you setup your web server to reverse proxy to the container on a particular endpoint in your server serving your Javascript and call it using your standard Javascript Ajax functions.

我的建议是,设置web服务器将代理反向到服务Javascript的服务器中的特定端点上的容器,并使用标准的Javascript Ajax函数调用它。

#8


0  

Doing this would require to break the browser sandbox. Try to let your server do the lookup and request that from the client side via XmlHttp.

这样做需要打破浏览器沙箱。尝试让服务器通过XmlHttp从客户端进行查找和请求。

#9


-1  

I don't think this is allowed by most browsers for security reasons, in a pure JavaScript context as the question asks.

出于安全考虑,我认为大多数浏览器都不允许这样做,在纯JavaScript环境中。

#10


-2  

My version is like this:

我的版本是这样的:

php on my server:

php在我的服务器:

<?php
    header('content-type: application/json; charset=utf-8');

    $data = json_encode($_SERVER['REMOTE_ADDR']);


    $callback = filter_input(INPUT_GET, 
                 'callback',
                 FILTER_SANITIZE_STRING, 
                 FILTER_FLAG_ENCODE_HIGH|FILTER_FLAG_ENCODE_LOW);
    echo $callback . '(' . $data . ');';
?>

jQuery on the page:

jQuery的页面:

var self = this;
$.ajax({
    url: this.url + "getip.php",
    data: null,
    type: 'GET',
    crossDomain: true,
    dataType: 'jsonp'

}).done( function( json ) {

    self.ip = json;

});

It works cross domain. It could use a status check. Working on that.

它是跨域。它可以使用状态检查。在那工作。

#11


-2  

Maybe I missed the point but in reply to NAVY guy here is how the browser can tell you the 'requestor's' IP address (albeit maybe only their service provider).

也许我错过了这一点,但在回答海军的问题时,浏览器可以告诉你“请求者”的IP地址(尽管可能只是他们的服务提供者)。

Place a script tag in the page to be rendered by the client that calls (has src pointing to) another server that is not loaded balanced (I realize that this means you need access to a 2nd server but hosting is cheap these days and you can set this up easily and cheaply).

放置一个脚本标签在页面呈现由客户机调用(src指着)另一个服务器不加载平衡(我知道这意味着您需要访问第二个服务器但托管这些天很便宜,你可以很容易实现和便宜)。

This is the kind of code that needs to be added to client page:

这是需要添加到客户端页面的代码:

On the other server "someServerIown" you need to have the ASP, ASPX or PHP page that;

在另一个服务器“someServerIown”上,需要有ASP、ASPX或PHP页面;

----- contains server code like this:

----包含如下服务器代码:

"<% Response.Write("var clientipaddress = '" & Request.ServerVariables("REMOTE_ADDR") & "';") %>" (without the outside dbl quotes :-))

“< %响应。写入(“var clientipaddress = '”和Request.ServerVariables(“REMOTE_ADDR”)和“;”)%>(没有外部dbl引号:-)

---- and writes this code back to script tag:

——将此代码写回脚本标签:

   var clientipaddress = '178.32.21.45';

This effectively creates a Javascript variable that you can access with Javascript on the page no less.

这有效地创建了一个Javascript变量,您可以在页面上使用Javascript进行访问。

Hopefully, you access this var and write the value to a form control ready for sending back.

希望您能够访问这个var并将值写入一个表单控件中,以便返回。

When the user posts or gets on the next request your Javascript and/or form sends the value of the variable that the "otherServerIown" has filled in for you, back to the server you would like it on.

当用户发布或获取下一个请求时,您的Javascript和/或表单将“otherServerIown”为您填充的变量的值发送回服务器。

This is how I get around the dumb load balancer we have that masks the client IP address and makes it appear as that of the Load balancer .... dumb ... dumb dumb dumb!

这就是我如何绕过我们愚蠢的负载均衡器面具客户机IP地址和使它出现的负载均衡器....愚蠢的…愚蠢的愚蠢的愚蠢!

I haven't given the exact solution because everyone's situation is a little different. The concept is sound, however. Also, note if you are doing this on an HTTPS page your "otherServerIOwn" must also deliver in that secure form otherwise Client is alerted to mixed content. And if you do have https then make sure ALL your certs are valid otherwise client also gets a warning.

我没有给出确切的答案,因为每个人的情况都有点不同。然而,这一概念是合理的。另外,请注意,如果您在HTTPS页面上执行此操作,那么您的“otherServerIOwn”也必须以该安全表单交付,否则客户端将被警告混合内容。如果您有https,那么请确保您的所有证书都是有效的,否则客户端也会收到警告。

Hope it helps someone! Sorry, it took a year to answer/contribute. :-)

希望它能帮助一些人!对不起,我花了一年的时间才回复/投稿。:-)

#12


-9  

If the client has Java installed, you could do something like this:

如果客户端安装了Java,您可以这样做:

ipAddress = java.net.InetAddress.getLocalHost().getHostAddress();

Other than that, you will probably have to use a server side script.

除此之外,您可能还需要使用服务器端脚本。