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.