Получение URL-адреса хэша и его использование в jQuery


135

Я хотел бы получить значение после хэша в URL текущей страницы, а затем иметь возможность применить это в новой функции ... например.

URL может быть

www.example.com/index.html#foo

И я хотел бы использовать это в сочетании со следующим фрагментом кода

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

Я предпочитаю / надеюсь, что есть какой-то способ схватить это и превратить в переменную, которую я затем смогу использовать во втором фрагменте кода.


8
У меня нет для вас кода, но вы должны убедиться, что входные данные санированы, так как это кажется готовым для внедрения кода.
Нейт Б

Понимание того, что этому вопросу уже почти десять лет, 'ul#foo:first'не имеет смысла, поскольку идентификаторы должны быть уникальными, поэтому добавление :firstв селектор является избыточным, если только вы не дублируете идентификаторы, которые недопустимы. Обратите внимание, что даже десять лет назад повторные идентификаторы были недействительными.
j08691

Все еще был неправ десять лет назад
Дуглас

Ответы:


280

Примечание редактора: приведенный ниже подход имеет серьезные последствия для безопасности и, в зависимости от используемой версии jQuery, может подвергать ваших пользователей атакам XSS. Для получения более подробной информации см. Обсуждение возможной атаки в комментариях к этому ответу или в этом объяснении на Security Stack Exchange .

Вы можете использовать location.hashсвойство, чтобы получить хеш текущей страницы:

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

Обратите внимание, что это свойство уже содержит #символ в начале.

На самом деле вам не нужен :firstпсевдо-селектор, так как вы используете селектор идентификаторов , предполагается, что идентификаторы уникальны в DOM.

Если вы хотите получить хеш из строки URL, вы можете использовать String.substringметод:

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

Совет: имейте в виду, что пользователь может изменять хэш по своему усмотрению, вводя что-либо в ваш селектор, вы должны проверить хэш перед его использованием.


30
Обратите внимание, что селекторы jQuery могут использоваться для выполнения пользовательского кода javascript, поэтому использование неанизированных хэшей ужасно, ужасно небезопасно. В последних версиях jQuery есть неполное исправление для селекторов, которые содержат # перед введенным кодом, но вы все равно рискуете, если уберете знак # в начале location.hash. Например var hash = location.hash.slice(1); $('ul.item'+hash).show().append($('#content'));это выполнит тег скрипта, помещенный в хеш. Это хорошая привычка использовать $('body').find('ul'+hash+':first')вместо $('ul'+hash+':first').
Tgr

40
Некоторые браузеры возвращают символ хеша, а некоторые нет, поэтому безопаснее использовать:var hash = location.hash.replace('#', '');
Тим

12
Алиса запускает веб-сайт, Боб посещает его, аутентифицирует и получает сессионный cookie. (Некоторое время здесь может пройти, Боб может даже закрыть свой браузер.) Чарли отправляет Бобу письмо с надписью «Проверьте эту классную ссылку!». Боб открывает ссылку, которая ведет на сайт, контролируемый Чарли. Страница перенаправляет браузер Боба на страницу сайта Алисы с полезной нагрузкой хэша. Полезная нагрузка выполняется, и, поскольку браузер по-прежнему запоминает файлы cookie, он может просто отправить их Чарли.
Tgr

2
@Tgr, спасибо за разработку и подключение точек. Этот конкретный пример делает меня (и, надеюсь, других) более склонным к бдительности в обеспечении безопасности.
snapfractalpop

2
@buffer: $(userInput)обычно небезопасно, поскольку $перегружен и может либо искать существующие узлы, либо создавать новые в зависимости от того, содержит ли строка <>символы. $(document).find(userInput)всегда будет искать существующие узлы, так что это менее опасно. Тем не менее, рекомендуется всегда дезинфицировать пользовательский ввод, например, если вы используете буквенно-цифровые идентификаторы, убедитесь, что они буквенно-цифровые.
Tgr

35

location.hash не является безопасным для IE , в случае IE (включая IE9), если ваша страница содержит iframe, то после обновления вручную внутри содержимого iframe получите значение location.hash (значение для загрузки первой страницы). значение, полученное вручную, отличается от значения location.hash, поэтому всегда извлекайте его через document.URL

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

7
Обновление: document.URL не содержит хеш-значения в Firefox 3.6, поэтому location.href является безопасным var hash = location.href.substr (location.href.indexOf ('#') + 1)
Deepak Patil

4

Для тех, кто ищет чистое решение javascript

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

Надеюсь, это сэкономит вам время.


3

Начиная с jQuery 1.9, :targetселектор будет соответствовать хешу URL. Так что вы могли бы сделать:

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

Который выберет элемент с идентификатором, соответствующим хешу, и покажет его.


Есть ли способ извлечь хэш в виде строки вместо идентификатора совпадения?
Ина

@ina Вы хотите получить хеш от jQuery :targetв виде строки? Если так, то я не верю в это.
j08691

1

Я бы посоветовал лучше сначала использовать cek, если на текущей странице есть хеш. Иначе это будет undefined.

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

1

Я использую это для устранения последствий для безопасности, отмеченных в ответе @ 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...
    }
});
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.