【问题标题】:Remove hash from URL, load the page at hash-less URL, then add hash to URL without reloading the page从 URL 中删除哈希,以无哈希 URL 加载页面,然后将哈希添加到 URL 而无需重新加载页面
【发布时间】:2013-06-04 21:19:52
【问题描述】:

我正在开发一个使用 AJAX 加载和一些 jQuery 动画的网站。

使用 JavaScript,我从动态生成的指向基于 PHP 的页面的链接中获取 href,然后将该 href 添加到 URL(在不可避免的 #/ 之后)。

到目前为止一切顺利,除非用户将页面添加为书签并尝试访问它,否则该用户将到达主页,而不是他/她希望访问的页面。

所以,当一个页面被直接访问时,不是通过点击网站的内部链接,我想从 url 中删除 #/,而是保留它后面的所有内容,这样被加书签的 URL 是这样的:

http://www.mysite.com/#/somepage

被重写为:

http://www.mysite.com/somepage

那么,在正确的页面 (http://www.mysite.com/somepage) 完成加载后,我想将 #/ 粘贴回 URL (http://www.mysite.com/#/somepage) 中的先前位置,无需重新加载页面(其中,多亏了我正在使用的聪明的 sn-p,它将确保导航的其余部分按应有的方式工作。)

所以:

  1. 在页面加载之前,检查 URL,如果它有 #/,请将其删除。
  2. 加载页面位于无哈希 url
  3. 使用#/ 重新显示网址,无需重新加载页面。

它甚至可行吗?如果是的话,我将不胜感激。

【问题讨论】:

标签: javascript url


【解决方案1】:

您正在尝试做的事情是可行的,但需要维护一个完整的 PITA,并且它不会在所有浏览器上都可用。除此之外,密钥位于最近扩展的history 对象中,以添加一组新的“技巧”。其完整文档可在 from MDN 获取。

您要执行此操作的是replaceState 命令。内容如下:

更新历史堆栈上的最新条目以具有指定的数据、标题和 URL(如果提供)。数据被 DOM 视为不透明的;您可以指定任何可以序列化的 JavaScript 对象。请注意,Firefox 目前忽略了 title 参数;有关详细信息,请参阅操作浏览器历史记录。

这将允许您在浏览器历史记录中替换当前页面,但在 URL 中。 URL 将与您拥有的完全相同 - 带有哈希。考虑到您的解决方案,没有必要更改它。

但是,您必须确保您的无哈希页面重定向到带有 history 对象的客户端的哈希存在页面,以保持一致性。这是唯一的要求。

【讨论】:

  • 这听起来很有希望,@Sebastien,只是我希望我能更好地理解它。能不能详细解释一下?
  • @KeithRules:window.history.replaceState({}, "Your page title", "/your/page/with/no/hash"); 将更改导航器中的 URL 在历史记录中将其标记为新页面。从那里,您需要做的就是使用 window.location.hash 添加主题标签。
  • 谢谢@Sebastien——你能告诉我如何为任何页面做到这一点吗?例如,对于 url 为 #/ 后跟任何内容的任何页面,以及任何页面标题?
【解决方案2】:

在页面加载之前,检查 URL,如果有 #/,将其删除。

不可能。片段 id 不会发送到服务器,因此您只能使用客户端代码访问它,并且需要页面加载(或至少开始加载)。

加载页面位于无哈希 url
用#/重新显示url,不重新加载页面

使用XMLHttpRequest获取数据,DOM更改文档以使用它,history API更改地址栏中的URL。

【讨论】:

  • 谢谢你,@Quentin。那么,“一旦页面开始加载,删除哈希,在无哈希 url 处重新加载页面,然后在不重新加载页面的情况下添加哈希”——这可行吗?
【解决方案3】:

正如其中一个答案所指出的,您无法在页面加载之前删除哈希。

但是,一旦页面开始加载,问题中描述的操作是可能的。

这是一种方法。

// Remove the hash and reload the page at url without hash 

if (window.location.href.indexOf('/#/')>=0) {
    window.location = window.location.href.replace(/\/#\//, '/');
} 

新页面开始加载后,您可以使用history.pushState 更新网址显示:

if ((window.location.href.indexOf('/#/')<1) && (location.pathname != "/")) {
     history.pushState({}, "page x",  location.protocol + '//' + location.host + '/#' + location.pathname);
}

您必须记住,尽管pushState 仅适用于从 Gecko 2.0 开始的浏览器,因此将哈希值放回 url 在旧版浏览器中将不起作用,期间。

这可能会导致一些不幸的情况。例如,假设您的网址http://www.mywebsite.com/somepage 被搜索引擎索引。用户单击该链接,在不支持 pushState 的旧版浏览器中访问您的网站,然后在浏览支持 AJAX 的网站时单击其他链接。该用户可能会到达

http://www.mysite.com/somepage/#/someotherpage

然后,随着用户不断点击,它只会变得更糟:

http://www.mysite.com/somepage/#/someotherpage/#/yetanotherpage/#/andsoon/#/andsoforth/

因此,您可能需要确保您的哈希值不会继续传播。

您还可以将哈希删除/替换代码包装在条件中:

if (history.pushState) {
// add hash
} else {
// provide some alternative
}

最后,看看这两个资源。您可能根本不需要哈希:History.jsjQuery Address

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-12-15
    • 2011-07-31
    • 2017-03-21
    • 2012-08-21
    • 2012-06-23
    • 2016-04-09
    • 2013-11-11
    • 1970-01-01
    相关资源
    最近更新 更多