Ottenere la posizione dell'hash dell'URL e usarla in jQuery


135

Vorrei ottenere il valore dopo un hash nell'URL della pagina corrente e quindi poterlo applicare in una nuova funzione ... ad es.

L'URL potrebbe essere

www.example.com/index.html#foo

E vorrei usarlo insieme al seguente pezzo di codice

$('ul#foo:first').show();

Sto presumendo / sperando che ci sia un modo per afferrarlo e trasformarlo in una variabile che posso quindi usare nel secondo pezzo di codice.


8
Non ho alcun codice per te, ma dovresti assicurarti di disinfettare l'input, poiché questo sembra maturo per l'iniezione di codice.
Nate B,

Comprendere che questa domanda ha quasi un decennio, 'ul#foo:first'non ha senso poiché gli ID devono essere univoci, pertanto l'aggiunta :firstal selettore è ridondante, a meno che non si stiano duplicando ID non validi. Si noti che anche dieci anni fa, gli ID ripetuti erano ancora non validi.
j08691,

Era ancora sbagliato un decennio fa
Douglas il

Risposte:


280

Nota del redattore: l'approccio seguente ha serie implicazioni per la sicurezza e, a seconda della versione di jQuery in uso, può esporre gli utenti ad attacchi XSS. Per maggiori dettagli, vedere la discussione sul possibile attacco nei commenti su questa risposta o questa spiegazione su Security Stack Exchange .

Puoi usare la location.hashproprietà per afferrare l'hash della pagina corrente:

var hash = window.location.hash;
$('ul'+hash+':first').show();

Si noti che questa proprietà contiene già il #simbolo all'inizio.

In realtà non è necessario lo :firstpseudo-selettore poiché si utilizza il selettore ID , si presume che gli ID siano univoci all'interno del DOM.

Nel caso in cui desideri ottenere l'hash da una stringa URL, puoi utilizzare il String.substringmetodo:

var url = "http://example.com/file.htm#foo";
var hash = url.substring(url.indexOf('#')); // '#foo'

Consiglio: tieni presente che l'utente può modificare l'hash come vuole, iniettando qualsiasi cosa al tuo selettore, dovresti controllare l'hash prima di usarlo.


30
Si noti che i selettori jQuery possono essere utilizzati per eseguire codice javascript personalizzato, quindi l'utilizzo di hash non dinamici è orribilmente, terribilmente insicuro. C'è una correzione a metà per questo nelle recenti versioni di jQuery per i selettori che contengono un # prima del codice iniettato, ma sei ancora a rischio se rimuovi il segno # dall'inizio di location.hash. Per esempio. var hash = location.hash.slice(1); $('ul.item'+hash).show().append($('#content'));questo eseguirà un tag script inserito nell'hash. È una buona abitudine usare al $('body').find('ul'+hash+':first')posto di $('ul'+hash+':first').
Tgr

40
Alcuni browser restituiscono il simbolo dell'hash, altri no, quindi è più sicuro usare:var hash = location.hash.replace('#', '');
Tim

12
Alice gestisce un sito Web, Bob lo visita, autentica e riceve un cookie di sessione. (Potrebbe passare un po 'di tempo qui, Bob potrebbe persino chiudere il suo browser.) Charlie invia a Bob una mail dicendo "dai un'occhiata a questo fantastico link!". Bob apre il collegamento, che conduce a un sito controllato da Charlie. La pagina reindirizza il browser di Bob a una pagina del sito di Alice con un payload di attacco nell'hash. Il payload viene eseguito e poiché il browser ricorda ancora i cookie, può semplicemente inviarli a Charlie.
Tgr

2
@Tgr, grazie per aver elaborato e collegato i punti. Questo esempio concreto rende me (e, si spera, altri) più incline alla vigilanza nel mantenere le cose sicure.
snapfractalpop,

2
@buffer: $(userInput)generalmente non è sicuro perché $è sovraccarico e potrebbe cercare nodi esistenti o crearne di nuovi a seconda che la stringa contenga <>caratteri. $(document).find(userInput)cercherà sempre i nodi esistenti, quindi è meno pericoloso. Detto questo, la migliore pratica è di disinfettare sempre l'input dell'utente, ad esempio se si utilizzano ID alfanumerici assicurarsi che sia alfanumerico.
Tgr

35

location.hash non è sicuro per IE , nel caso di IE (incluso IE9), se la tua pagina contiene iframe, dopo l'aggiornamento manuale all'interno del contenuto iframe ottieni il valore location.hash è vecchio (valore per il caricamento della prima pagina). mentre il valore recuperato manualmente è diverso da location.hash, quindi recuperalo sempre tramite document.URL

var hash = document.URL.substr(document.URL.indexOf('#')+1) 

7
Aggiornamento: document.URL non contiene il valore hash su Firefox 3.6 quindi location.href è sicuro var hash = location.href.substr (location.href.indexOf ('#') + 1)
Deepak Patil

4

Per coloro che cercano una soluzione javascript pura

 document.getElementById(location.hash.substring(1)).style.display = 'block'

Spero che questo ti faccia risparmiare un po 'di tempo.


3

Da jQuery 1.9, il :targetselettore corrisponderà all'hash dell'URL. Quindi potresti fare:

$(":target").show(); // or $("ul:target").show();

Che selezionerebbe l'elemento con l'ID corrispondente all'hash e lo mostrerebbe.


c'è un modo per estrarre l'hash come stringa anziché come ID di corrispondenza?
ina,

@ina Intendi ottenere l'hash da jQuery :targetcome stringa? Se è così non ci credo.
j08691,

1

Vorrei suggerire prima cek meglio se la pagina corrente ha un hash. Altrimenti lo sarà undefined.

$(window).on('load', function(){        
    if( location.hash && location.hash.length ) {
       var hash = decodeURIComponent(location.hash.substr(1));
       $('ul'+hash+':first').show();;
    }       
});

1

Sto usando questo per affrontare le implicazioni di sicurezza annotate nella risposta di @ CMS.

// example 1: www.example.com/index.html#foo

// load correct subpage from URL hash if it exists
$(window).on('load', function () {
    var hash = window.location.hash;
    if (hash) {
        hash = hash.replace('#',''); // strip the # at the beginning of the string
        hash = hash.replace(/([^a-z0-9]+)/gi, '-'); // strip all non-alphanumeric characters
        hash = '#' + hash; // hash now equals #foo with example 1

        // do stuff with hash
        $( 'ul' + hash + ':first' ).show();
        // etc...
    }
});
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.