Como verificar com javascript se a conexão é um host local?


99

Quero verificar no meu javascript se a página que está sendo carregada está na minha máquina local.

A razão pela qual desejo fazer isso é que, durante o desenvolvimento, gosto de ter certeza de que a validação do lado do servidor (C #) está funcionando corretamente. Então, eu gosto de ver os erros do lado do cliente e do lado do servidor aparecerem.

Então, enquanto estou testando, tenho um sinalizador no meu jquery validate que sempre permite a passagem de dados inválidos. Desta forma, vejo os erros do lado do cliente e do servidor de uma só vez.

No entanto, agora eu tenho que ir e mudar manualmente para frente e para trás ao passar do desenvolvimento para a produção.


3
Eu apenas alertaria qualquer um que use qualquer um desses métodos em qualquer uma dessas respostas para "adicionar" funcionalidade ao sistema, especialmente se essa funcionalidade puder ser usada para expor informações ou dados seguros de outra forma em seu sistema. Usar essa técnica para "remover" a funcionalidade faz sentido, entretanto. Por exemplo, se você deseja suprimir o rastreamento de analítica de disparo em seu ambiente de desenvolvimento, mesmo que faça isso em seu ambiente de produção. Basta pensar cuidadosamente sobre o que você está expondo por meio de uma condição ou alternância do lado do navegador e como isso pode se tornar uma vulnerabilidade de segurança.
Javid Jamae,

Respostas:


205

A location.hostnamevariável fornece o host atual. Isso deve ser o suficiente para você determinar em que ambiente está.

if (location.hostname === "localhost" || location.hostname === "127.0.0.1")
    alert("It's a local server!");

14
Não existe uma solução mais geral / "pega-tudo" que também cobriria os casos de uso de 127.0.0.1, etc.?
jacobq de

8
Isso é simplesmente errado. muitas pessoas editam seu arquivo de host para que a palavra 'localhost' não seja encontrada
vsync

4
concordo. Isto está errado. Também não funcionará ao acessar um arquivo "local" por meio de uma unidade de rede.
ProblemsOfSumit

1
@Sumit através da interface do arquivo, você pode verificar se o nome do host está vazio
chacham15

1
Uhh não tenho certeza porque cada um está afirmando isso como errado. Este simples recorte funciona perfeitamente para mim no host local e na produção. Meu software conhece o tempo para veicular anúncios - ou não, com uma simples linha de código. Obrigado OP.
Andy

30

se iniciar html estático no navegador, por exemplo, de um local como file:///C:/Documents and Settings/Administrator/Desktop/detectar "localhost", não funcionará. location.hostnameretornará uma string vazia. tão

if (location.hostname === "localhost" || location.hostname === "127.0.0.1" || location.hostname === "")
    alert("It's a local server!");

Eu encontrei exatamente esse problema e, embora eu mesmo descobrisse a solução, essa resposta ainda deveria estar acima.
domsson

6

Ainda não é um problema, mas pode ser uma pequena melhoria. Agora você pode criar uma variedade de domínios e usar .includes

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

if (LOCAL_DOMAINS.includes(window.location.hostname))
  alert("It's a local server!");

3

É assim que ele é verificado no React, registra o service worker , uma boa maneira de verificar se você está no localhost verificando o nome do host, incluindo localhost e IPv6 , e iniciar a correspondência com 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}$/
    )
);

2

Uma maneira fácil de fazer isso seria apenas verificar o nome do host em relação ao host local ou verificar seu nome de domínio personalizado em uma substring, neste caso urls ".local", como 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!");
}

2

Forma mais curta usando a mesma mecânica de outros scripts:

if ( ["localhost", "127.0.0.1", ""].includes(window.location.hostname) ) {
     console.log("It's local host !");
}

2

Este também cobre alguns casos comuns em que os IPs da rede local começam com 10.0.ou 192.168.ou Bonjour como domínio terminando em .local:

export function isLocalNetwork(hostname = window.location.hostname) {
  return (
    (['localhost', '127.0.0.1', '', '::1'].includes(hostname))
    || (hostname.startsWith('192.168.'))
    || (hostname.startsWith('10.0.'))
    || (hostname.endsWith('.local'))
  )
}

1

Você pode detectar em um de seus códigos por trás das páginas com c #, assim:

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

Ou se quiser fazer isso a partir do script do cliente, você pode verificar o valor de window.location.host.

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

Espero que isto ajude.


3
location.host inclui o nome do host E a porta. Em vez disso, use location.hostname.
pmont

1
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;
}

0

As respostas acima principalmente resolvem o problema, mas ...

  • E se localhost não for necessariamente 'localhost /'?
  • E se você quiser fazer a validação FE durante o desenvolvimento?
  • E se você quiser comportamentos diferentes durante o desenvolvimento
    (por exemplo , validação, seja validação, sem validação )

Uma solução é definir o hash do local e verificá-lo.

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

Você pode adicionar opções ilimitadas com um interruptor

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

Esta solução ainda tem algum trabalho manual e pode ser adulterada.
A1rPun

Acho que o "trabalho manual" é insignificante, adulterando também, já que podemos enviar o que quisermos sem a aprovação do javascript e a maioria dos frameworks tem filtros que atenuam os ataques antes que a solicitação chegue ao aplicativo. Talvez permitir que o OP ignore a validação do lado do servidor seja um risco, mas foi adicionado apenas para mostrar a utilidade de usar uma chave no hash.
Shanimal

Nunca uso localhost ou loopback porque colocar na lista de permissões dezenas de clientes internacionalizados (clinetA.com, clientA.de, clientB.com, clientB.au, etc ...) rapidamente se tornaria um pesadelo. Decidi oferecer essa solução porque ela não se preocupa com o domínio e pode ser verificada em um site ativo sem um patch.
Shanimal

0

A expressão regular é mais lenta *, mas curta e organizada. Além disso, ninguém aqui verifica o localhost IPv6 (:: 1)

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

Ele verifica o localhost geral, o domínio .local e o arquivo: (nome do host vazio).

*) No Chrome, o desempenho de [].includes(...)é o melhor (42 ms), seguido por loop simples (for, while) com verificação de item de array (119 ms), depois [].indexOf(...) > -1(289 ms) e finalmente o regexp (566 ms). Mas essas medidas são de alguma forma relativas, porque navegadores diferentes são otimizados de forma diferente. Em FF 52 ESR includese indexOfcom resultados semelhantes, regexp é 2 × mais lento e o loop 6 × mais lento.


0

Com base nos comentários acima, a seguinte expressão regular me ajudou a verificar se o url é 'localhost', algum endereço IP IPv4 ou 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)
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.