我想使用客户端JavaScript进行DNS查找(主机名到IP地址),并从客户端计算机上查看。这是否可能?
我想使用客户端JavaScript进行DNS查找(主机名到IP地址),并从客户端计算机上查看。这是否可能?
编辑: 这个问题让我很痒,所以我在谷歌应用引擎上搭建了一个JSONP服务,可以返回客户端的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>
太棒了,不需要服务器代理。
纯JS无法实现。如果您有一个在同一域下打印它的服务器脚本,您可以发送XMLHttpRequest来读取它。
我知道这个问题很久以前就被问过了,但是我想提供一个更新的答案。
您可以通过支持它的DNS解析程序将DNS查询发送到HTTPS上。 DOH的标准在RFC 8484中描述。
这与所有其他答案建议的类似,只是DoH实际上是DNS协议通过HTTPS。它还是一个“拟议中”的Internet标准,正在变得非常流行。例如,一些主要的浏览器支持它或计划支持它(Chrome、Edge、Firefox),微软正在将其构建到他们的操作系统中。
DoH的目的之一是:
允许Web应用程序通过现有的浏览器API以一种符合CORS(跨源资源共享)的安全方式访问DNS信息
有一个专门为Web应用程序从中进行DNS查找而制作的开源工具叫做dohjs。它执行如RFC 8484所述的DNS over HTTPS(DoH)wireformat查询。它支持GET和POST方法。
完整披露:我是dohjs的贡献者。
这里还有一个类似的JavaScript库 - https://github.com/sc0Vu/doh-js-client。我个人没有使用过这个库,但我认为它也可以在客户端使用。
如果您不想麻烦于DNS wireformat,Google和Cloudflare都提供了DNS over HTTPS的JSON API。
https://dns.google/resolve?
https://cloudflare-dns.com/dns-query?
使用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给出的GET和POST的示例(请参见https://www.rfc-editor.org/rfc/rfc8484#section-4.1.1):
GET示例:
第一个示例请求使用GET请求“www.example.com”。
:method = GET
:scheme = https
:authority = dnsserver.example.net
:path = /dns-query?dns=AAABAAABAAAAAAAAA3d3dwdleGFtcGxlA2NvbQAAAQAB
accept = application/dns-message
POST示例:
使用POST方法相同的DNS查询“www.example.com”如下:
:method = POST
:scheme = https
:authority = dnsserver.example.net
:path = /dns-query
accept = application/dns-message
content-type = 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
您可以在以下几个地方找到一些支持DNS over HTTPS的公共DNS解析器列表:
以上资源中,我认为Curl的wiki上的列表和DNSCrypt列表可能是最完整和最经常更新的。Curl的页面还包括一系列用于DoH的开源工具(服务器、代理、客户端库等)列表。
在 JavaScript 标准库中没有主机或 IP 地址的概念。因此,您需要访问某些外部服务来查找主机名。
我建议托管一个 CGI-BIN 程序,该程序可以查找主机名的 IP 地址,并通过 JavaScript 访问它。
虽然已经很晚了,但我猜很多人仍然通过“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.";
}
托管的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!
有一个第三方服务,提供了一个适用于CORS的REST API,可以从浏览器中执行DNS查找 - https://exana.io/tools/dns/
我知道这是一个老问题,但我的解决方案可能有助于其他人。
我发现使这个过程变得容易的 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/上看到这个功能。
ip-api.com
执行 DNS 查找并通过 JSONP 返回结果。虽然这在许多情况下可能运行良好,但如果您正在解析的主机名使用地理 DNS 解析,则世界各地的不同位置可能会看到从查找返回的不同 IP 地址。因此,客户端看到的 IP 可能与 ip-api.com
看到的 IP 不同。将该注释添加到您的答案中可能值得一试。 - Simon EastDNS.Query("dns-js.com",
DNS.QueryType.A,
function(data) {
console.log(data);
});
许多人说你需要使用外部服务并调用它。这只会从服务器角度获取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"
]
}
自Firefox v60版本开始,WebExtensions已经内置了API:
https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/dns/resolve
browser
,所以我想知道它是否被删除了。 - Kevin Ghadyani