Ich möchte clientseitiges Javascript verwenden, um eine DNS-Suche (Hostname zu IP-Adresse) vom Client-Computer aus durchzuführen. Ist das möglich?
Ich möchte clientseitiges Javascript verwenden, um eine DNS-Suche (Hostname zu IP-Adresse) vom Client-Computer aus durchzuführen. Ist das möglich?
Antworten:
In der Javascript-Standardbibliothek gibt es keine Vorstellung von Hosts oder IP-Adressen. Sie müssen also auf einen externen Dienst zugreifen, um nach Hostnamen für Sie zu suchen.
Ich empfehle, einen CGI-Bin zu hosten, der die IP-Adresse eines Hostnamens nachschlägt und über Javascript darauf zugreift.
Bearbeiten : Diese Frage hat mich gejuckt, daher habe ich einen JSONP-Webservice in Google App Engine eingerichtet, der die IP-Adresse des Clients zurückgibt. Verwendung:
<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>
Ja, es werden keine Server-Proxys benötigt.
Pure JS kann nicht. Wenn Sie ein Serverskript unter derselben Domäne haben, die es druckt, können Sie eine XMLHttpRequest senden, um es zu lesen.
Sehr spät, aber ich denke, viele Leute werden immer noch über "Google Airlines" hier landen. Ein moderater Ansatz ist die Verwendung von WebRTC, für das keine Serverunterstützung erforderlich ist.
https://hacking.ventures/local-ip-discovery-with-html5-webrtc-security-and-privacy-risk/
Der nächste Code ist ein Kopieren und Einfügen von 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.";
}
Die gehostete JSONP-Version funktioniert wie ein Zauber, aber es scheint, dass sie an den meisten Tagen (Eastern Time) in der Nacht über ihre Ressourcen geht, sodass ich meine eigene Version erstellen musste.
So habe ich es mit PHP geschafft:
<?php
header('content-type: application/json; charset=utf-8');
$data = json_encode($_SERVER['REMOTE_ADDR']);
echo $_GET['callback'] . '(' . $data . ');';
?>
Dann ist das Javascript genau das gleiche wie zuvor, nur kein Array:
<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>
So einfach ist das!
Randnotiz: Reinigen Sie Ihr $ _GET unbedingt, wenn Sie es in einer öffentlich zugänglichen Umgebung verwenden!
Ich weiß, dass diese Frage vor sehr langer Zeit gestellt wurde, aber ich dachte, ich würde eine neuere Antwort anbieten.
Sie können DNS-Abfragen über HTTPS an DNS-Resolver senden, die dies unterstützen. Der Standard für DOH ist in RFC 8484 beschrieben .
Dies ist ähnlich wie in allen anderen Antworten, nur dass DoH tatsächlich das DNS-Protokoll über HTTPS ist. Es ist auch ein "vorgeschlagener" Internetstandard und wird immer beliebter. Einige große Browser unterstützen es beispielsweise oder haben Pläne, es zu unterstützen (Chrome, Edge, Firefox), und Microsoft ist dabei, es in ihr Betriebssystem zu integrieren.
Einer der Zwecke von DoH ist:
Ermöglichen, dass Webanwendungen über vorhandene Browser-APIs auf DNS-Informationen zugreifen können, und zwar auf sichere Weise im Einklang mit CORS (Cross Origin Resource Sharing)
Es gibt ein Open-Source-Tool, das speziell für DNS-Lookups von Webanwendungen namens dohjs entwickelt wurde . Es führt DNS über HTTPS (DoH) -Drahtformatabfragen durch, wie in RFC 8484 beschrieben . Es unterstützt sowohl GET- als auch POST-Methoden.
Vollständige Offenlegung: Ich trage zu Dohjs bei.
Wenn Sie sich nicht mit dem DNS-Drahtformat beschäftigen möchten, bieten sowohl Google als auch Cloudflare JSON-APIs für DNS über HTTPS an.
Beispiel-Javascript-Code zum Nachschlagen von example.com mit der JSON DOH-API von Google:
var response = await fetch('https://dns.google/resolve?name=example.com');
var json = await response.json();
console.log(json);
Hier sind die Beispiele, die der RFC sowohl für GET als auch für POST gibt (siehe https://tools.ietf.org/html/rfc8484#section-4.1.1 ):
GET Beispiel:
Die erste Beispielanforderung verwendet GET, um "www.example.com" anzufordern.
: method = GET
: Schema = https
: Authority = dnsserver.example.net
: Pfad = / dns-Abfrage? dns = AAABAAABAAAAAAAAA3d3dwdleGFtcGxlA2NvbQAAAQAB
accept = application / dns-message
POST-Beispiel:
Dieselbe DNS-Abfrage für "www.example.com" unter Verwendung der POST-Methode lautet:
: Methode = POST
: Schema = https
: Autorität = dnsserver.example.net
: Pfad = / DNS-Abfrage
akzeptieren = Anwendung / DNS-Nachricht
Inhaltstyp = Anwendung / DNS-Nachricht
Inhalt-Länge = 33<33 Bytes, dargestellt durch die folgende Hex-Codierung> 00 00 01 00 00 01 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
Eine Liste einiger öffentlicher DNS-Resolver, die DNS über HTTPS unterstützen, finden Sie an mehreren Stellen:
Von den oben genannten Ressourcen würde ich sagen, dass die Liste in Curls Wiki und die DNSCrypt-Liste wahrscheinlich die vollständigste und am häufigsten aktualisierte sind. Die Seite von Curl enthält auch eine Liste von Open Source-Tools für DoH (Server, Proxys, Client-Bibliotheken usw.).
Ich bin mir bewusst, dass dies eine alte Frage ist, aber meine Lösung kann anderen helfen.
Ich finde, dass die JSON (P) -Dienste, die dies einfach machen, nicht ewig dauern, aber das folgende JavaScript funktioniert zum Zeitpunkt des Schreibens gut für mich.
<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>
Das Obige schreibt die IP meines Servers auf die Seite, auf der er sich befindet, aber das Skript kann geändert werden, um eine beliebige IP zu finden, indem 'zero.eu.org' in einen anderen Domainnamen geändert wird. Dies kann in Aktion auf meiner Seite unter http://meon.zero.eu.org/ gesehen werden.
Es gibt einen Drittanbieter-Service, der eine CORS-freundliche REST-API zur Durchführung von DNS-Suchvorgängen über den Browser bereitstellt - https://exana.io/tools/dns/
Wie viele Leute sagten, müssen Sie einen externen Dienst nutzen und ihn anrufen. Und das bringt Ihnen nur die DNS-Auflösung aus der Serverperspektive.
Wenn das gut genug ist und Sie nur eine DNS-Auflösung benötigen, können Sie den folgenden Docker-Container verwenden:
https://github.com/kuralabs/docker-webaiodns
Endpunkte:
[GET] /ipv6/[domain]
: Führen Sie eine DNS-Auflösung für eine bestimmte Domäne durch und geben Sie die zugehörigen IPv6-Adressen zurück.
{
"addresses": [
"2a01:91ff::f03c:7e01:51bd:fe1f"
]
}
[GET] /ipv4/[domain]
: Führen Sie eine DNS-Auflösung für eine bestimmte Domäne durch und geben Sie die zugehörigen IPv4-Adressen zurück.
{
"addresses": [
"139.180.232.162"
]
}
Ich empfehle, dass Sie Ihren Webserver so einrichten, dass er den Proxy für den Container auf einem bestimmten Endpunkt Ihres Servers, der Ihr Javascript bereitstellt, umkehrt und ihn mit Ihren Standard-Javascript-Ajax-Funktionen aufruft.
Es gibt eine Javascript-Bibliothek DNS-JS.com , die genau dies tut.
DNS.Query("dns-js.com",
DNS.QueryType.A,
function(data) {
console.log(data);
});
Firefox verfügt seit v60 über eine integrierte API für WebExtensions:
https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/dns/resolve
browser
gibt es in Firefox 64 Beta nicht, daher frage ich mich, ob das entfernt wurde.
dns
Genehmigung erforderlich ist und das Skript nicht als Inhaltsskript ausgeführt werden darf (wie browser.dns
auch hier nicht
Sicher, Sie können dies tun, ohne einen Zusatz zu verwenden, nur reines Javascript. browser.dns.resolve("example.com");
Wenn Sie diese DNS- Methode verwenden , diese jedoch nur mit FIREFOX 60 kompatibel ist, finden Sie weitere Informationen unter MDN https://developer.mozilla.org/en-US/docs / Mozilla / Add-Ons / WebExtensions / API / DNS / Resolution
Ich denke nicht, dass dies von den meisten Browsern aus Sicherheitsgründen in einem reinen JavaScript-Kontext erlaubt ist, wie die Frage stellt.
Vielleicht habe ich den Punkt verpasst, aber als Antwort auf NAVY kann der Browser Ihnen die IP-Adresse des Anforderers mitteilen (wenn auch vielleicht nur dessen Dienstanbieter).
Platzieren Sie ein Skript-Tag auf der Seite, die vom Client gerendert werden soll, der einen anderen Server aufruft (auf den src verweist), der nicht ausgeglichen geladen ist einfach und kostengünstig einrichten).
Dies ist die Art von Code, die der Client-Seite hinzugefügt werden muss:
Auf dem anderen Server "someServerIown" muss die ASP-, ASPX- oder PHP-Seite vorhanden sein.
----- enthält folgenden Servercode:
"<% Response.Write (" var clientipaddress = '"& Request.ServerVariables (" REMOTE_ADDR ") &"'; ")%>" (ohne die externen dbl-Anführungszeichen :-))
---- und schreibt diesen Code zurück in das Skript-Tag:
var clientipaddress = '178.32.21.45';
Dadurch wird effektiv eine Javascript-Variable erstellt, auf die Sie mit Javascript auf der Seite nicht weniger zugreifen können.
Hoffentlich greifen Sie auf diese Variable zu und schreiben den Wert in ein Formularsteuerelement, das zum Zurücksenden bereit ist.
Wenn der Benutzer die nächste Anfrage stellt oder erhält, sendet Ihr Javascript und / oder Formular den Wert der Variablen, die der "otherServerIown" für Sie ausgefüllt hat, zurück an den Server, auf dem Sie ihn haben möchten.
So komme ich um den dummen Load Balancer herum, der die Client-IP-Adresse maskiert und sie als die des Load Balancers erscheinen lässt ... dumm ... dumm dumm dumm!
Ich habe nicht die genaue Lösung angegeben, weil die Situation bei jedem etwas anders ist. Das Konzept ist jedoch solide. Beachten Sie außerdem, dass Ihr "otherServerIOwn", wenn Sie dies auf einer HTTPS-Seite tun, auch in dieser sicheren Form liefern muss, da der Client sonst auf gemischte Inhalte aufmerksam gemacht wird. Und wenn Sie https haben, stellen Sie sicher, dass ALLE Ihre Zertifikate gültig sind, andernfalls erhält der Client auch eine Warnung.
Hoffe es hilft jemandem! Entschuldigung, es hat ein Jahr gedauert, um zu antworten / beizutragen. :-)
Meine Version ist wie folgt:
PHP auf meinem Server:
<?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 auf der Seite:
var self = this;
$.ajax({
url: this.url + "getip.php",
data: null,
type: 'GET',
crossDomain: true,
dataType: 'jsonp'
}).done( function( json ) {
self.ip = json;
});
Es funktioniert domänenübergreifend. Es könnte eine Statusprüfung verwenden. Daran arbeiten.
Wenn auf dem Client Java installiert ist, können Sie Folgendes tun:
ipAddress = java.net.InetAddress.getLocalHost().getHostAddress();
Ansonsten müssen Sie wahrscheinlich ein serverseitiges Skript verwenden.