147

I want to have a check in my javascript if the page loading up is on my local machine.

The reason why I want to do that is that when I developing I like to make sure that both my server side(C#) validation is working correctly. So I like to see both the client side and server sides errors to show up.

So while I am testing I have a flag in my jquery validate stuff that just always lets invalid data go through. This way I see the client side and server errors at one go.

However right now I have to manually go and change back and forth when going from development to production.

Damjan Pavlica
  • 31,277
  • 10
  • 71
  • 76
chobo2
  • 83,322
  • 195
  • 530
  • 832
  • 6
    I would just caution anybody using of any of these methods in any of these answers to "add" functionality to the system, especially if said functionality could be used to expose otherwise secure information or data in your system. Using this technique to "remove" functionality makes sense, however. For example, if you want to suppress firing analytics tracking in your development environment, even though you do it in your production environment. Just think carefully about what you're exposing through a browser-side conditional or toggle and how it could become a security vulnerability. – Javid Jamae Apr 02 '18 at 04:58

13 Answers13

280

The location.hostname variable gives you the current host. That should be enough for you to determine which environment you are in.

if (location.hostname === "localhost" || location.hostname === "127.0.0.1")
    alert("It's a local server!");
ZitRo
  • 1,163
  • 15
  • 24
Unicron
  • 7,275
  • 1
  • 26
  • 19
  • 15
    Isn't there a more general / "catch-all" solution that would also cover cases of using 127.0.0.1, etc.? – jacobq Oct 10 '12 at 18:21
  • 9
    This is just wrong. many people edit their host file so the word 'localhost' won't be found – vsync Aug 01 '13 at 18:57
  • 4
    i agree. This is wrong. Also won't work when accessing a "local" file through a network drive. – ProblemsOfSumit Aug 13 '13 at 14:59
  • 1
    @Sumit through the file interface you can check that the hostname is empty – chacham15 Jan 22 '15 at 21:08
  • 3
    Uhh not sure why every one is stating this as wrong. This simple snipped works perfect for me on localhost and production. My software knows weather to serve ads - or not, with 1 simple line of code. Thanks OP. – Andy Mar 17 '17 at 20:33
  • While the solution might be too specific, it should be tagged as correct, it works under most circumstances; in any case, local-specific settings should NEVER get to prod IMHO, inject stuff while working locally if you should, or enforce using relevant local-only hostnames such as `prod_domain.local` instead. – mrArias Dec 15 '17 at 08:27
  • You could also include `file:///` – FloatingRock Jun 27 '18 at 13:21
  • this solution doesn't work if i use a name in the etc/hosts file of the os where browser runs instead of using localhost or 127.0.0.1 directly – Dee Sep 06 '18 at 04:22
47

if launching static html in browser, eg from location like file:///C:/Documents and Settings/Administrator/Desktop/ detecting "localhost" will not work. location.hostname will return empty string. so

if (location.hostname === "localhost" || location.hostname === "127.0.0.1" || location.hostname === "")
    alert("It's a local server!");
Alexei - check Codidact
  • 22,016
  • 16
  • 145
  • 164
  • 1
    I ran into this exact issue and while I figured the solution myself, this answer should still be higher up. – domsson Mar 14 '17 at 10:48
24

That's how it get checked in React, register service worker, good way to check if you are on localhost by checking hostname, including localhost and IPv6, and matching start with 127:

const isLocalhost = Boolean(
    window.location.hostname === 'localhost' ||
    // [::1] is the IPv6 localhost address.
    window.location.hostname === '[::1]' ||
    // 127.0.0.1/8 is considered localhost for IPv4.
    window.location.hostname.match(
        /^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/
    )
);
Alireza
  • 100,211
  • 27
  • 269
  • 172
16

Still not a catch all but it might be a little improvement. You can now create an array of domains and use .includes

const LOCAL_DOMAINS = ["localhost", "127.0.0.1", ...];

if (LOCAL_DOMAINS.includes(window.location.hostname))
  alert("It's a local server!");
daniele bertella
  • 695
  • 1
  • 7
  • 14
12

The following code checks whether an address is localhost, that is, whether it points to the same device from which this request is made.

export function isLocalHost(hostname = window.location.hostname) {
  return ['localhost', '127.0.0.1', '', '::1'].includes(hostname)
}

The following code also checks if the request goes into the local network. Some common cases where local network IPs start with 10.0. or 192.168. or mDNS / Bonjour like domains ending on .local:

export function isLocalNetwork(hostname = window.location.hostname) {
  return (
    (['localhost', '127.0.0.1', '', '::1'].includes(hostname))
    || (hostname.startsWith('192.168.'))
    || (hostname.startsWith('10.'))
    || (hostname.endsWith('.local'))
  )
}
Holtwick
  • 1,849
  • 23
  • 29
  • I don't believe this is correct? `.local`, etc do not mean that the host is on the local machine which is what the question was. Those will be on other devices on the local network. – Julian Knight Apr 07 '23 at 14:43
  • 2
    `.local` is reserved for mDNS which is designed for "small networks". In most cases this is on the local network. See https://en.wikipedia.org/wiki/Multicast_DNS But you are right, the question was "is connection localhost" and this is only true for the first line of the conditions. I'll update my answer. Thanks! – Holtwick Apr 08 '23 at 15:19
11

Shortest form using same mechanic as other scripts:

if ( ["localhost", "127.0.0.1", ""].includes(window.location.hostname) ) {
     console.log("It's local host !");
}
TarmoPikaro
  • 4,723
  • 2
  • 50
  • 62
4
const LOCAL_DOMAINS = [ "localhost", "127.0.0.1" ];

/* offline || development */
if ( LOCAL_DOMAINS.includes(location.hostname) )
{
    BASE_URL_PUBLIC = location.hostname + "/folder/website/"; // your project folder
}

/* online || production */
else
{
    BASE_URL_PUBLIC = location.hostname;
}
antelove
  • 3,216
  • 26
  • 20
3

An easy way to do this would be to just check the hostname against localhost or check your custom domain name against a substring, in this case ".local" urls, such as http://testsite.local

var myUrlPattern = '.local';
if (window.location.hostname === "localhost" || location.hostname === "127.0.0.1" || window.location.hostname.indexOf(myUrlPattern) >= 0) {
    alert("It's a local server!");
}
Summit
  • 1,223
  • 2
  • 12
  • 15
1

You could detect in one of your code behind pages with c#, like this:

if ((Request.Url.Host.ToLower() == "localhost"))
{
    // ..., maybe set an asp:Literal value that's in the js
}

Or if you want to do it from client script, you could check the value of window.location.host.

if (window.location.host == "localhost")
{
    // Do whatever
}

Hope this helps.

Samuel Meacham
  • 10,215
  • 7
  • 44
  • 50
0

The above answers mostly solve the problem but...

  • What if localhost isn't necessarily 'localhost/'?
  • What if you want to do FE validation during development?
  • What if you want different behaviors during dev
    (fe validation, be validation, no validation)

One solution is to set the location hash and check it.

http://myname.foo.com/form.html#devValidation

You could add unlimited options with a switch

switch(location.hash) {}
    case '#devValidation':
        // log the results and post the form
        break;
    case '#beValidation':
        // skip front end validation entirely
        break;
    case '#noValidation':
        // skip all validation $('[name=validationType']).val('novalidation');
        break;
    case '#feValidation':
    default:
        // do fe validation
        break;
}
Shanimal
  • 11,517
  • 7
  • 63
  • 76
  • This solution still has some manual work and it can be tampered with. – A1rPun Jan 09 '17 at 10:33
  • I think the "manual work" is insignificant, tampering as well since we can submit whatever we like without javascript's approval and most frameworks have filters that mitigate attacks before the request ever reaches the application. Maybe allowing the OP to skip server side validation is a risk, but it was only added to show the utility of using a key in the hash. – Shanimal Jan 09 '17 at 18:27
  • I never use localhost or the loopback because whitelisting dozens of internationalized clients (clinetA.com, clientA.de, clientB.com, clientB.au, etc...) would quickly become a nightmare. I decided to offer this solution because it doesn't care about the domain and can be checked in a live site without a patch. – Shanimal Jan 09 '17 at 18:28
0

Regular expression is slower*, but short and neat. Also, nobody here checks for IPv6 localhost (::1)

/localhost|127\.0\.0\.1|::1|\.local|^$/i.test(location.hostname)

It checks for general localhost, .local domain and file: (empty hostname).

*) In Chrome, performance of [].includes(...) is the best (42 ms), followed by simple loop (for, while) with array item checking (119 ms), then [].indexOf(...) > -1 (289 ms) and finally the regexp (566 ms). But those measurements are somehow relative, because different browsers are optimized differently. In FF 52 ESR includes and indexOf have similar results, regexp is 2× slower and loop 6× slower.

mikiqex
  • 5,023
  • 2
  • 24
  • 22
0

Based on the above comments th following regular expression has helped me to verify if the url is 'localhost', any IP adress IPv4 or IPv6.

window.location.hostname.match(/localhost|[0-9]{2,3}\.[0-9]{2,3}\.[0-9]{2,3}\.[0-9]{2,3}|::1|\.local|^$/gi)
saddy
  • 11
  • 3
0

Many of the answers here miss some edge-cases. For example, depending on DNS/hosts/etc, you could have something.localhost.

So here is a slightly more comprehensive ES6 answer:

const localHost = ['localhost', '127.0.0.1', '::1', ''].includes(window.location.hostname) || window.location.hostname.endsWith('.localhost')
Julian Knight
  • 4,716
  • 2
  • 29
  • 42