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

Posted

技术标签:

【中文标题】获取 URL 哈希位置,并在 jQuery 中使用它【英文标题】:Getting URL hash location, and using it in jQuery 【发布时间】:2010-12-21 19:27:38 【问题描述】:

我想在当前页面的 URL 中获取哈希后的值,然后能够将其应用到新函数中......例如。

网址可以是

www.example.com/index.html#foo

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

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

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

【问题讨论】:

我没有任何代码给你,但你应该确保清理输入,因为这似乎适合代码注入。 了解这个问题已经有将近十年的历史了,'ul#foo:first' 没有意义,因为 ID 必须 是唯一的,因此在选择器中添加 :first 是多余的,除非您复制无效的 ID。请注意,即使在十年前,重复的 ID 仍然无效。 十年前还是错了 【参考方案1】:

编者注:以下方法具有严重的安全隐患,并且根据您使用的 jQuery 版本,可能会暴露您的用户应对 XSS 攻击。有关更多详细信息,请参阅此答案或 this explanation on Security Stack Exchange 的 cmets 中对可能攻击的讨论。

可以使用location.hash属性来获取当前页面的hash:

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

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

实际上您不需要:first 伪选择器,因为您使用的是ID selector,假定ID 在DOM 中是唯一的。

如果您想从 URL 字符串中获取哈希值,可以使用 String.substring 方法:

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

建议:请注意,用户可以根据需要更改散列,向您的选择器注入任何内容,您应该在使用之前检查散列。

【讨论】:

请注意,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') 是一个好习惯。 有些浏览器返回井号,有些没有,所以使用起来更安全:var hash = location.hash.replace('#', ''); Alice 运行一个网站,Bob 访问它,验证并接收会话 cookie。 (这里可能会经过一段时间,Bob 甚至可能会关闭他的浏览器。)Charlie 给 Bob 发了一封邮件,上面写着“看看这个很酷的链接!”。 Bob 打开链接,该链接指向一个由 Charlie 控制的站点。该页面将 Bob 的浏览器重定向到 Alice 站点上的一个页面,该页面在哈希中带有攻击载荷。有效载荷被执行,由于浏览器仍然记得 cookie,它可以将它们发送给 Charlie。 @Tgr,感谢您详细说明和连接这些点。这个具体的例子让我(希望是其他人)更倾向于保持警惕以确保安全。 @buffer: $(userInput) 通常是不安全的,因为$ 已超载,可能会搜索现有节点或创建新节点,具体取决于字符串是否包含<> 字符。 $(document).find(userInput) 将始终搜索现有节点,因此不安全。也就是说,最佳实践是始终清理用户输入,例如如果您使用字母数字 ID,请确保它是字母数字。【参考方案2】:

location.hash 对 IE 不安全,如果是 IE(包括 IE9),如果您的页面包含 iframe,则在 iframe 内容内手动刷新后,获取 location.hash 值是旧的(值用于第一页加载)。虽然手动检索的值与 location.hash 不同,但请始终通过 document.URL 检索它

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

【讨论】:

更新:document.URL 在 Firefox 3.6 上不包含哈希值,因此 location.href 是安全的 var hash = location.href.substr(location.href.indexOf('#')+1) 【参考方案3】:

对于那些正在寻找纯 JavaScript 解决方案的人

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

希望这可以为您节省一些时间。

【讨论】:

【参考方案4】:

从 jQuery 1.9 开始,:target 选择器将匹配 URL 哈希。所以你可以这样做:

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

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

【讨论】:

有没有办法将哈希提取为字符串而不是匹配 id? @ina 你的意思是从 jQuery 的:target 获取哈希作为字符串?如果是这样,我不相信。【参考方案5】:

如果当前页面有散列,我会建议先使用更好的 cek。否则将是undefined

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

【讨论】:

【参考方案6】:

我正在使用它来解决@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...
    
);

【讨论】:

以上是关于获取 URL 哈希位置,并在 jQuery 中使用它的主要内容,如果未能解决你的问题,请参考以下文章

如何从 URL 获取片段标识符(哈希 # 后的值)?

使用 JS/jQuery 从 URL 中删除哈希

使用 URL 哈希触发现有 jquery

从 jquery ajax statuscode 401 获取位置重定向 url

[并在php和jQuery中获取并显示基于月份的数据

jquery 获取URL相对/绝对路径问题