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

时间:2008-09-19 15:06:16

标签: javascript dns

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

16 个答案:

答案 0 :(得分:86)

修改:这个问题给了我一个痒,所以我在Google App Engine上建立了一个返回客户端IP地址的JSONP网络服务。用法:

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

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


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

答案 1 :(得分:31)

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

我建议托管一个cgi-bin,它查找主机名的ip-address并通过javascript访问它。

答案 2 :(得分:25)

很晚,但我想很多人仍会通过“Google Airlines”登陆这里。现代方法是使用不需要服务器支持的WebRTC。

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

下一代码是来自http://net.ipcalf.com/

的复制和粘贴
// 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.";
}   

答案 3 :(得分:14)

托管的JSONP版本就像魅力一样,但它似乎在大多数时间(东部时间)的夜间都会覆盖其资源,因此我必须创建自己的版本。

这就是我用PHP完成它的方式:

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

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

然后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>

这很简单!

旁注:如果您在任何面向公众的环境中使用它,请务必清理$ _GET!

答案 4 :(得分:2)

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

我发现使这很容易的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>

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

答案 5 :(得分:2)

有第三方服务提供CORS友好的REST API,以便从浏览器执行DNS查找 - https://exana.io/tools/dns/

答案 6 :(得分:1)

许多人说你需要使用外部服务并调用它。这只会从服务器角度为您提供DNS解析。

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

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

<强>终点:

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

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

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

 {
     "addresses": [
         "139.180.232.162"
     ]
 }

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

答案 7 :(得分:1)

我知道这个问题是很久以前问过的,但我想我会提供一个更新的答案。

基于HTTPS(DOH)的DNS

您可以通过HTTPS将DNS查询发送到支持它的DNS解析器。 RFC 8484中描述了DOH的标准。

基于HTTPS JSON API的DNS

如果您不想打扰DNS线格式,那么Google和Cloudflare都提供基于HTTPS的DNS的JSON API。

使用Google的JSON DOH API查找example.com的示例Javascript代码:

var response = await fetch('https://dns.google/resolve?name=example.com');
var json = await response.json();
console.log(json);

RFC中采用线格式的DOH GET和POST的示例

以下是RFC为GET和POST提供的示例(请参见https://tools.ietf.org/html/rfc8484#section-4.1.1):

获取示例:

  

第一个示例请求使用GET请求“ www.example.com”。

     

:方法= GET
    :scheme = https
    :authority = dnsserver.example.net
    :path = / dns-query?dns = AAABAAABAAAAAAAAA3d3dwdleGFtcGxlA2NvbQAAAQAB
    接受= application / dns-message

POST示例:

  

使用POST方法对“ www.example.com”进行相同的DNS查询将      是:

     

:方法= POST
    :scheme = https
    :authority = dnsserver.example.net
    :path = / dns-query
    接受= application / dns-message
    内容类型= application / dns-message
    content-length = 33

     

<由以下十六进制编码表示的33个字节>      00 00 01 00 00 01 00 00 00 00 00 00 03 77 77 77      07 65 78 61 6d 70 6c 65 03 63 6f 6d 00 00 01 00      01

其他发送DOH查询的地方

您可以在几个地方找到一些支持DNS over HTTPS的公共DNS解析器的列表:

在以上资源中,我想说的是Curl Wiki上的列表可能是最完整,更新最频繁的列表。

答案 8 :(得分:0)

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

答案 9 :(得分:0)

通过使用dns browser.dns.resolve("example.com");的这种方法,可以确保不使用任何纯JavaScript即可完成此操作 但它仅与FIREFOX 60兼容,您可以在MDN https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/dns/resolve

上查看更多信息。

答案 10 :(得分:0)

有一个JavaScript库DNS-JS.com就是这样做的。

DNS.Query("dns-js.com",
    DNS.QueryType.A,
    function(data) {
        console.log(data);
});

答案 11 :(得分:-1)

出于安全原因,我不认为大多数浏览器允许这样做,在问题要求的纯JavaScript上下文中。

答案 12 :(得分:-1)

自v60以来,Firefox为此WebExtensions内置了一个API:

https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/dns/resolve

答案 13 :(得分:-2)

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

在页面中放置一个脚本标记,由客户端调用(有src指向)另一个未加载平衡的服务器(我意识到这意味着你需要访问第二台服务器,但这些天托管很便宜你可以轻松便宜地设置它。)

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

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

-----包含这样的服务器代码:

“&LT;%  Response.Write(“var clientipaddress ='”&amp; Request.ServerVariables(“REMOTE_ADDR”)&amp;“';”)  %&gt;”中 (没有外部的dbl引号: - ))

----并将此代码写回脚本标记:

   var clientipaddress = '178.32.21.45';

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

希望您访问此var并将值写入表单控件,准备发回。

当用户发布或接收下一个请求时,您的Javascript和/或表单会发送“otherServerIown”为您填写的变量的值,然后返回到您希望的服务器上。

这就是我如何绕过我们所拥有的愚蠢负载均衡器来屏蔽客户端IP地址并使其显示为负载均衡器.... dumb ...哑巴哑巴笨蛋!

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

希望它有所帮助!对不起,花了一年的时间来回答/贡献。 : - )

答案 14 :(得分:-3)

我的版本是这样的:

我的服务器上的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:

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

}).done( function( json ) {

    self.ip = json;

});

它适用于跨域。 它可以使用状态检查。正在努力。

答案 15 :(得分:-10)

如果客户端安装了Java,您可以执行以下操作:

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

除此之外,您可能必须使用服务器端脚本。

相关问题