Existe uma maneira de alterar a barra de endereço do navegador sem atualizar a página?

91

Estou desenvolvendo um aplicativo web. Nele, tenho uma seção chamada categorias que, sempre que um usuário clica em uma das categorias, um painel de atualização carrega o conteúdo apropriado.

Depois que o usuário clica na categoria, quero alterar o URL da barra de endereços do navegador de

www.mysite.com/products 

para algo como

www.mysite.com/products/{selectedCat} 

sem atualizar a página.
Existe algum tipo de API JavaScript que posso usar para fazer isso?

Luiso
fonte

Respostas:

157

Com HTML5, você pode modificar o url sem recarregar:

Se você quiser fazer uma nova postagem no histórico do navegador (ou seja, o botão Voltar funcionará)

window.history.pushState('Object', 'Title', '/new-url');

Se você apenas deseja alterar o url sem poder voltar

window.history.replaceState('Object', 'Title', '/another-new-url');

O objeto pode ser usado para navegação ajax:

window.history.pushState({ id: 35 }, 'Viewing item #35', '/item/35');

window.onpopstate = function (e) {
  var id = e.state.id;
  load_item(id);
};

Leia mais aqui: http://www.w3.org/TR/html5-author/history.html

Uma solução alternativa: https://github.com/browserstate/history.js

Alfred
fonte
4
+1 também observe; estes alteram o pathe / ou query stringno URL; eles não podem alterar o protocolo, domínio ou porta (pois isso seria um problema de segurança, como outros apontaram). A hashfunção acima pode alterar a âncora (ou id do fragmento)
Chris S de
2
apenas dizendo, em seu exemplo '/ item / 35'}, há um extra} adicionado
Zhanger
Só como uma pergunta lateral, há uma maneira de permitir que esses URLs sejam indexados no Google?
Peter Featherstone
1
Uma biblioteca melhor parece ser github.com/browserstate/history.js, ela é mantida ativamente e amplamente usada, enquanto o forte-history.js ficou inativo por 3 anos.
Gonfi den Tschal
2
Observe que o firefox não oferece suporte a títulos, então use document.title = "novo título".
0fnt
31

Para adicionar ao que os caras já disseram, edite a propriedade window.location.hash para corresponder à URL que você deseja em sua função onclick.

window.location.hash = 'category-name'; // address bar would become http://example.com/#category-name
Roborourke
fonte
existe alguma maneira de alterar o url sem o símbolo '#' no URL?
SHEKHAR SHETE
7

Acredito que manipular diretamente a barra de endereço para um url completamente diferente sem mover para esse url não é permitido por razões de segurança, se você estiver satisfeito com isso

www.mysite.com/products/#{selectedCat}

ou seja, um link de estilo de âncora na mesma página, em seguida, examine os vários scripts de histórico / "botão voltar" que agora estão presentes na maioria das bibliotecas javascript.

A menção do painel de atualização me leva a supor que você está usando asp.net, nesse caso, o controle de histórico do asp.net ajax é um bom lugar para começar

Justin Wignall
fonte
3

Não acho que isso seja possível (pelo menos mudar para um endereço totalmente diferente), pois seria um uso indevido não intuitivo da barra de endereço e poderia promover ataques de phishing.

Galuego
fonte
Em vez de não ser intuitivo, acho que você não deveria ser capaz de fazer isso, porque pode ser usado incorretamente para ataques de phishing. De qualquer forma, isso é +1.
OregonGhost
Sim, isso acabou de me ocorrer. Não é uma boa ideia. Obrigado OregonGhost.
Galwegian
1
Eu não acho que é possível ... Saída Wikimapia ... Como você arrastar o mapa ao redor, o URL é alterado ...
Shivasubramanian A
@ Shivasubramanian-a: Eu olhei para o Wikimapia e, de fato, eles apenas usam a técnica sugerida por somej e descrita por sanchothefat: apenas mudar o nome da âncora. Que é seguro contra phishing ...
PhiLho
-1

Isso não pode ser feito da maneira que você está dizendo. O método sugerido por somej.net é o mais próximo que você pode obter. Na verdade, é uma prática muito comum na era AJAX. Até o Gmail usa isso.

aalaap
fonte
-1

"window.location.hash"

como sugerido por sanchothefat deve ser a única maneira de fazer isso. Porque em todos os lugares que vi esse recurso, está sempre após o # na URL.


fonte