Can I perform a DNS lookup (hostname to IP address) using client-side Javascript?

JavascriptDns

Javascript Problem Overview


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 Solutions


Solution 1 - Javascript

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:

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

Solution 2 - Javascript

I know this question was asked a very long time ago, but I figured I'd offer a more recent answer.

DNS over HTTPS (DoH)

You can send DNS queries over HTTPS to DNS resolvers that support it. The standard for DOH is described in RFC 8484.

This is a similar thing to what all the other answers suggest, only that DoH is actually the DNS protocol over HTTPS. It's also a "proposed" Internet standard and it's becoming quite popular. For example, some major browsers either support it or have plans to support it (Chrome, Edge, Firefox), and Microsoft is in the process of building it into their operating system.

One of the purposes of DoH is: >allowing web applications to access DNS information via existing browser APIs in a safe way consistent with Cross Origin Resource Sharing (CORS)

There's an open source tool made especially for doing DNS lookups from web applications called dohjs. It does DNS over HTTPS (DoH) wireformat queries as described in RFC 8484. It supports both GET and POST methods.

Full disclosure: I am a contributor to dohjs.

Another JavaScript library with similar features is found here - https://github.com/sc0Vu/doh-js-client. I haven't used this one personally, but I think it would work client side as well.

DNS over HTTPS JSON APIs

If you don't want to bother with DNS wireformat, both Google and Cloudflare offer JSON APIs for DNS over HTTPS.

Example Javascript code to lookup example.com with Google's JSON DOH API:

var response = await fetch('https://dns.google/resolve?name=example.com');
var json = await response.json();
console.log(json);
Examples from the RFC for DOH GET and POST with wireformat

Here are the examples the RFC gives for both GET and POST (see https://www.rfc-editor.org/rfc/rfc8484#section-4.1.1):

GET example:

> The first example request uses GET to request "www.example.com".

> :method = GET
> :scheme = https
> :authority = dnsserver.example.net
> :path = /dns-query?dns=AAABAAABAAAAAAAAA3d3dwdleGFtcGxlA2NvbQAAAQAB
> accept = application/dns-message

POST example:

>The same DNS query for "www.example.com", using the POST method would be:

> :method = POST
> :scheme = https
> :authority = dnsserver.example.net
> :path = /dns-query
> accept = application/dns-message
> content-type = application/dns-message
> content-length = 33

> <33 bytes represented by the following hex encoding> 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

Other places to send DOH queries

You can find a list of some public DNS resolvers that support DNS over HTTPS in a couple places:

Of the above resources, I'd say that the list on Curl's wiki and the DNSCrypt list are are probably the most complete and the most frequently updated. Curl's page also includes a list of open source tools for DoH (servers, proxies, client libs, etc).

Solution 3 - Javascript

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.

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

Solution 4 - Javascript

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.

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

Next code is a copy&paste from 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.";
}   

Solution 5 - Javascript

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.

This is how I accomplished it with 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:

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

Solution 6 - Javascript

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/

Solution 7 - Javascript

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.

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

Solution 8 - Javascript

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.

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

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

Endpoints:

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

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

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

 {
     "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.

Solution 9 - Javascript

There is a javascript library DNS-JS.com that does just this.

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

Solution 10 - Javascript

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.

Solution 11 - Javascript

Firefox has a built-in API for this since v60, for WebExtensions:

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

Solution 12 - Javascript

sure you can do that without using any addition, just pure javascript, by using this method of dns browser.dns.resolve("example.com"); but it is compatible just with FIREFOX 60 you can see more information on MDN https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/dns/resolve

Solution 13 - Javascript

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

Solution 14 - Javascript

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

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

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

Solution 15 - Javascript

My version is like this:

php on my 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 on the page:

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.

Solution 16 - Javascript

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

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

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionNoah JacobsonView Question on Stackoverflow
Solution 1 - JavascriptZachView Answer on Stackoverflow
Solution 2 - JavascriptkimboView Answer on Stackoverflow
Solution 3 - JavascriptHans SjunnessonView Answer on Stackoverflow
Solution 4 - JavascriptearizonView Answer on Stackoverflow
Solution 5 - JavascripttcoleView Answer on Stackoverflow
Solution 6 - Javascriptuser670908View Answer on Stackoverflow
Solution 7 - JavascriptNeville HillyerView Answer on Stackoverflow
Solution 8 - JavascriptHavokView Answer on Stackoverflow
Solution 9 - JavascriptFiach ReidView Answer on Stackoverflow
Solution 10 - JavascriptTomalakView Answer on Stackoverflow
Solution 11 - JavascriptSaturnusView Answer on Stackoverflow
Solution 12 - JavascriptYassine FarroudView Answer on Stackoverflow
Solution 13 - JavascriptNick CraverView Answer on Stackoverflow
Solution 14 - JavascriptBill SView Answer on Stackoverflow
Solution 15 - JavascriptJoeriView Answer on Stackoverflow
Solution 16 - JavascriptAlex FortView Answer on Stackoverflow