144 votes

Obtenir l'emplacement du hachage d'URL et l'utiliser en jQuery

Je voudrais obtenir la valeur après un hash dans l'URL de la page actuelle, puis être en mesure d'appliquer ceci dans une nouvelle fonction... par exemple.

L'URL pourrait être

www.example.com/index.html#foo

Et j'aimerais utiliser ceci en conjonction avec le morceau de code suivant

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

Je suppose un peu / j'espère qu'il y a un moyen de récupérer ceci, et de le transformer en une variable que je peux ensuite utiliser dans le deuxième morceau de code.

10 votes

Je n'ai pas de code pour vous, mais vous devriez vous assurer de nettoyer l'entrée, car cela semble être propice à l'injection de code.

0 votes

En comprenant que cette question remonte de près d'une décennie, 'ul#foo:first' ne semble pas logique puisque les IDs doivent être uniques, donc ajouter :first au sélecteur est redondant, à moins que vous ne dupliquiez des IDs ce qui est invalide. Notez que même il y a une décennie, les IDs répétés étaient toujours invalides.

0 votes

Encore avait tort il y a une décennie

297voto

CMS Points 315406

Note de l'éditeur: l'approche ci-dessous a de sérieuses implications en matière de sécurité et, en fonction de la version de jQuery que vous utilisez, peut exposer vos utilisateurs à des attaques XSS. Pour plus de détails, voir la discussion de l'attaque possible dans les commentaires de cette réponse ou cette explication sur Security Stack Exchange.

Vous pouvez utiliser la propriété location.hash pour récupérer le hash de la page actuelle :

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

Remarquez que cette propriété contient déjà le symbole # au début.

En fait, vous n'avez pas besoin du pseudo-sélecteur :first puisque vous utilisez le sélecteur ID, il est supposé que les IDs sont uniques dans le DOM.

Dans le cas où vous souhaitez obtenir le hash à partir d'une chaîne d'URL, vous pouvez utiliser la méthode String.substring :

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

Conseil: Sachez que l'utilisateur peut changer le hash comme il le souhaite, injectant n'importe quoi dans votre sélecteur, vous devriez vérifier le hash avant de l'utiliser.

30 votes

Notez que les sélecteurs jQuery peuvent être utilisés pour exécuter du code JavaScript personnalisé, donc l'utilisation de hachages non-sanitisés est terriblement, terriblement insecure. Il y a une solution bâclée pour cela dans les versions récentes de jQuery pour les sélecteurs qui contiennent un # avant le code injecté, mais vous êtes toujours en danger si vous supprimez le marqueur # du début de location.hash. Par exemple, var hash = location.hash.slice(1); $('ul.item'+hash).show().append($('#content')); cela exécutera une balise script mise dans le hash. Il est bon d'habitude d'utiliser $('body').find('ul'+hash+':first') au lieu de $('ul'+hash+':first').

42 votes

Certains navigateurs renvoient le symbole dièse, tandis que d'autres ne le font pas, il est donc plus sûr d'utiliser : var hash = location.hash.replace('#', '');

0 votes

@Tgr Quand vous dites que "l'utilisation de hachages non-sanitisés est terriblement, terriblement peu sécuritaire", pouvez-vous expliquer ce qui peut être fait? Parlons-nous d'un utilisateur piratant son propre ordinateur? Je ne peux tout simplement pas comprendre quelle est la véritable vulnérabilité et j'apprécierais vraiment une explication.

37voto

Deepak Patil Points 456

location.hash n'est pas sûr pour IE, dans le cas d'IE (y compris IE9), si votre page contient une iframe, alors après un rafraîchissement manuel à l'intérieur du contenu de l'iframe, la valeur de location.hash est ancienne (valeur lors du premier chargement de la page). Alors que la valeur manuellement récupérée est différente de location.hash, donc toujours la récupérer à travers document.URL

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

7 votes

Mise à jour : document.URL ne contient pas de valeur de hachage sur Firefox 3.6, donc location.href est sûr var hash = location.href.substr(location.href.indexOf('#')+1)

6voto

LIUFA Points 3642

Pour ceux qui recherchent une solution purement en javascript

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

J'espère que cela vous fait gagner du temps.

5voto

j08691 Points 86464

Depuis jQuery 1.9, le sélecteur :target correspondra au hash de l'URL. Vous pouvez donc faire :

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

Cela sélectionnerait l'élément avec l'ID correspondant au hash et l'afficherait.

0 votes

Y a-t-il un moyen d'extraire le hash en tant que chaîne au lieu de l'ID de correspondance?

0 votes

@ina Voulez-vous dire obtenir le hash de :target de jQuery sous forme de chaîne de caractères? Si c'est le cas, je ne crois pas.

3voto

squarecandy Points 882

Je l'utilise pour aborder les implications de sécurité notées dans la réponse de @CMS.

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

// charger la sous-page correcte à partir de la hash URL si elle existe
$(window).on('load', function () {
    var hash = window.location.hash;
    if (hash) {
        hash = hash.replace('#',''); // supprimer le # au début de la chaîne
        hash = hash.replace(/([^a-z0-9]+)/gi, '-'); // supprimer tous les caractères non alphanumériques
        hash = '#' + hash; // hash est maintenant égal à #foo avec l'exemple 1

        // faire quelque chose avec hash
        $( 'ul' + hash + ':first' ).show();
        // etc...
    }
});

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X