Abrufen des URL-Hash-Speicherorts und Verwenden in jQuery


135

Ich möchte den Wert nach einem Hash in der URL der aktuellen Seite abrufen und ihn dann in einer neuen Funktion anwenden können ... z.

Die URL könnte sein

www.example.com/index.html#foo

Und ich möchte dies in Verbindung mit dem folgenden Code verwenden

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

Ich gehe davon aus / hoffe, dass es eine Möglichkeit gibt, dies zu erfassen und es in eine Variable umzuwandeln, die ich dann im zweiten Code verwenden kann.


8
Ich habe keinen Code für Sie, aber Sie sollten sicherstellen, dass die Eingabe bereinigt wird, da dies für die Code-Injektion reif erscheint.
Nate B

Das Verständnis , dass diese Frage fast ein Jahrzehnt alt ist, macht 'ul#foo:first'keinen Sinn , da IDs müssen eindeutig sein, damit das Hinzufügen :firstzu dem Selektor ist überflüssig, es sei denn , Sie IDs sind Vervielfältigungen , die ungültig ist. Beachten Sie, dass wiederholte IDs noch vor einem Jahrzehnt ungültig waren.
j08691

War vor einem Jahrzehnt immer noch falsch
Douglas

Antworten:


280

Anmerkung des Herausgebers: Der folgende Ansatz hat schwerwiegende Auswirkungen auf die Sicherheit und kann Ihre Benutzer abhängig von der von Ihnen verwendeten Version von jQuery XSS-Angriffen aussetzen. Weitere Informationen finden Sie in der Diskussion des möglichen Angriffs in den Kommentaren zu dieser Antwort oder in dieser Erklärung zu Security Stack Exchange .

Mit der location.hashEigenschaft können Sie den Hash der aktuellen Seite abrufen:

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

Beachten Sie, dass diese Eigenschaft das #Symbol bereits am Anfang enthält.

Tatsächlich benötigen Sie den :firstPseudo-Selektor nicht, da Sie den ID-Selektor verwenden . Es wird davon ausgegangen, dass IDs innerhalb des DOM eindeutig sind .

Wenn Sie den Hash von einer URL-Zeichenfolge abrufen möchten, können Sie die folgende String.substringMethode verwenden:

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

Hinweis: Beachten Sie, dass der Benutzer den Hash nach Belieben ändern kann , indem Sie etwas in Ihren Selektor injizieren. Sie sollten den Hash überprüfen, bevor Sie ihn verwenden.


30
Beachten Sie, dass jQuery-Selektoren zum Ausführen von benutzerdefiniertem Javascript-Code verwendet werden können, sodass die Verwendung von nicht bereinigten Hashes schrecklich, schrecklich unsicher ist. In den letzten jQuery-Versionen für Selektoren, die ein # vor dem injizierten Code enthalten, gibt es dafür eine halbherzige Korrektur. Sie sind jedoch weiterhin gefährdet, wenn Sie die # -Markierung am Anfang von location.hash entfernen. Z.B. var hash = location.hash.slice(1); $('ul.item'+hash).show().append($('#content'));Dadurch wird ein Skript-Tag ausgeführt, das in den Hash eingefügt wird. Es ist eine gute Angewohnheit, $('body').find('ul'+hash+':first')statt zu verwenden $('ul'+hash+':first').
Tgr

40
Einige Brower geben das Hash-Symbol zurück, andere nicht. Daher ist es sicherer:var hash = location.hash.replace('#', '');
Tim

12
Alice betreibt eine Website, Bob besucht sie, authentifiziert sich und erhält ein Sitzungscookie. (Hier könnte einige Zeit vergehen, Bob könnte sogar seinen Browser schließen.) Charlie sendet Bob eine E-Mail mit der Aufschrift "Check out this cool link!". Bob öffnet den Link, der zu einer von Charlie kontrollierten Site führt. Die Seite leitet Bobs Browser auf eine Seite auf Alices Website mit einer Angriffsnutzlast im Hash weiter. Die Nutzdaten werden ausgeführt, und da sich der Browser die Cookies noch merkt, kann er sie einfach an Charlie senden.
Tgr

2
@ Tgr, danke, dass du die Punkte ausgearbeitet und verbunden hast. Dieses konkrete Beispiel macht mich (und hoffentlich auch andere) eher zu Wachsamkeit, wenn es darum geht, die Dinge sicher zu halten.
Snapfractalpop

2
@buffer: $(userInput)ist im Allgemeinen unsicher, da $es überladen ist und entweder nach vorhandenen Knoten suchen oder neue erstellen kann, je nachdem, ob die Zeichenfolge <>Zeichen enthält . $(document).find(userInput)sucht immer nach vorhandenen Knoten, damit diese weniger unsicher sind. Die beste Vorgehensweise besteht jedoch darin, Benutzereingaben immer zu bereinigen. Wenn Sie beispielsweise alphanumerische IDs verwenden, stellen Sie sicher, dass diese alphanumerisch sind.
Tgr

35

location.hash ist für IE nicht sicher. Wenn IE (einschließlich IE9) IE enthält, enthält Ihre Seite nach der manuellen Aktualisierung des iframe-Inhalts den Wert location.hash (Wert für das Laden der ersten Seite). Der manuell abgerufene Wert unterscheidet sich von location.hash. Rufen Sie ihn daher immer über document.URL ab

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

7
Update: document.URL enthält keinen Hash-Wert in Firefox 3.6, daher ist location.href sicher. Var hash = location.href.substr (location.href.indexOf ('#') + 1)
Deepak Patil

4

Für diejenigen, die nach einer reinen Javascript-Lösung suchen

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

Hoffe das spart dir etwas Zeit.


3

Seit jQuery 1.9 stimmt der :targetSelektor mit dem URL-Hash überein. So könnten Sie tun:

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

Welches würde das Element mit der ID auswählen, die mit dem Hash übereinstimmt, und es anzeigen.


Gibt es eine Möglichkeit, den Hash als Zeichenfolge anstelle der Übereinstimmungs-ID zu extrahieren?
Ina

@ina Meinst du den Hash von jQuery's :targetals String bekommen? Wenn ja, glaube ich nicht.
j08691

1

Ich würde empfehlen, zuerst besser zu cek, wenn die aktuelle Seite einen Hash hat. Sonst wird es sein undefined.

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

1

Ich verwende dies, um die Sicherheitsaspekte zu beheben, die in der Antwort von @ CMS angegeben sind.

// 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...
    }
});
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.