获取URL哈希位置,并在jQuery中使用它


135

我想在当前页面的URL中获取哈希值后的值,然后将其应用于新函数中。

该网址可能是

www.example.com/index.html#foo

我想将其与以下代码结合使用

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

我有点假设/希望有某种方法可以将其捕获,并将其转换为变量,然后在第二段代码中使用。


8
我没有适合您的任何代码,但是您应该确保清理输入,因为对于代码注入来说似乎已经成熟。
Nate B

'ul#foo:first'因为ID 必须是唯一的,所以理解这个问题已经存在了将近十年了,这没有任何意义,因此:first,除非您要复制无效的ID,否则添加到选择器是多余的。请注意,即使在十年前,重复的ID仍然无效。
j08691

十年前还是错的
道格拉斯(Douglas)

Answers:


280

编者注:以下方法具有严重的安全隐患,并且根据所使用的jQuery版本,可能使您的用户遭受XSS攻击。有关更多详细信息,请参阅此答案的注释或有关Security Stack Exchange的解释中有关可能的攻击的讨论。

您可以使用该location.hash属性来获取当前页面的哈希值:

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

请注意,此属性#开头已包含符号。

实际上,:first由于使用ID选择器,因此您不需要伪选择,前提是ID 在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 2012年

40
有些浏览器返回哈希符号,有些则没有,因此使用起来更安全:var hash = location.hash.replace('#', '');
蒂姆(Tim)

12
爱丽丝(Alice)运行一个网站,鲍勃(Bob)访问该网站,进行身份验证并接收会话cookie。(有些时间可能会过去,鲍勃甚至可能会关闭浏览器。)查理给鲍勃发了一封邮件,说“查看这个很酷的链接!”。鲍勃打开链接,该链接指向由查理控制的网站。该页面将Bob的浏览器重定向到Alice站点上的页面,哈希中包含攻击有效载荷。有效负载已执行,并且由于浏览器仍然记住cookie,因此可以将它们发送给Charlie。
Tgr 2012年

2
@Tgr,谢谢您精心设计和连接各个点。这个具体的例子使我(并希望其他人)更倾向于保持安全。
snapfractalpop 2012年

2
@buffer:$(userInput)通常是不安全的,因为$它已过载,并可能根据字符串是否包含<>字符来搜索现有节点或创建新节点。$(document).find(userInput)会始终搜索现有节点,因此不太安全。也就是说,最佳做法是始终清除用户输入,例如,如果您使用字母数字ID,请确保它是字母数字。
Tgr

35

location.hash对于IE是不安全的,对于IE(包括IE9)而言,如果您的页面包含iframe,则在iframe内容内部手动刷新后,获取location.hash值是old(首次加载页面的值)。虽然手动检索的值与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


3

从jQuery 1.9开始,:target选择器将匹配URL哈希。因此,您可以执行以下操作:

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

它将选择ID与哈希匹配的元素并显示它。


有没有办法将哈希提取为字符串而不是匹配ID?
ina

@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...
    }
});
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.