167

我正在研究使用 HTML5 History API 来解决 AJAX 加载内容的深度链接问题,但我正在努力起步。有没有人知道任何好的资源?

我想使用它,因为这似乎是一种很好的方法,可以让那些被发送链接的人可能没有打开 JS。当有 JS 的人向没有 JS 的人发送链接时,许多解决方案都会失败。

我最初的研究似乎指向 JS 中的 History API 和 pushState 方法。

http://html5demos.com/history

4

9 回答 9

181

对于一个很棒的教程,你只需要关于这个功能的 Mozilla 开发者网络页面:https ://developer.mozilla.org/en/DOM/Manipulating_the_browser_history

不幸的是,HTML5 History API 在所有 HTML5 浏览器中的实现方式都不同(使其不一致且有问题),并且没有针对 HTML4 浏览器的回退。幸运的是,History.js为 HTML5 浏览器提供了交叉兼容性(确保所有 HTML5 浏览器按预期工作),并可选择为 HTML4 浏览器提供哈希回退(包括对数据、标题、pushState 和 replaceState 功能的维护支持)。

您可以在此处阅读有关 History.js 的更多信息: https ://github.com/browserstate/history.js

有关 Hashbangs VS Hashes VS HTML5 History API 的文章,请参见此处: https ://github.com/browserstate/history.js/wiki/Intelligent-State-Handling

于 2011-01-30T13:47:56.270 回答
33

我从“潜入 HTML 5”中受益匪浅。解释和演示更容易和重点。历史章节 - http://diveintohtml5.info/history.html 和历史演示 - http://diveintohtml5.info/examples/history/fer.html

于 2011-09-29T05:42:48.383 回答
29

请记住,在使用 HTML5 pushstate 时,如果用户复制或收藏一个深层链接并再次访问它,那么这将是一个直接的服务器命中,将 404 所以你需要做好准备,即使是 pushstate js 库也无济于事你。最简单的解决方案是向您的 Nginx 或 Apache 服务器添加重写规则,如下所示:

Apache(如果您使用的是虚拟主机,则在您的虚拟主机中):

<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteBase /
    RewriteRule ^index\.html$ - [L]
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule . /index.html [L]
 </IfModule>

Nginx

rewrite ^(.+)$ /index.html last;
于 2012-05-18T06:04:47.830 回答
6

HTML5历史规范很古怪。

history.pushState()不会自行分派popstate事件或加载新页面。它只是为了将国家推向历史。这是单页应用程序的“撤消”功能。您必须手动调度popstate事件或使用history.go()来导航到新状态。这个想法是路由器可以监听popstate事件并为您进行导航。

需要注意的一些事项:

  • history.pushState()并且history.replaceState()不要分派popstate事件。
  • history.back(), history.forward(), 和浏览器的后退和前进按钮会调度popstate事件。
  • history.go()history.go(0)重新加载整个页面,不要分派popstate事件。
  • history.go(-1)(back 1 page) 和history.go(1)(forward 1 page) 执行调度popstate事件。

您可以使用这样的历史 API 来推送新状态并调度 popstate 事件。

history.pushState({message:'New State!'}, 'New Title', '/link'); window.dispatchEvent(new PopStateEvent('popstate', { bubbles: false, cancelable: false, state: history.state }));

popstate然后用路由器监听事件。

于 2014-08-31T21:05:51.267 回答
4

您可以尝试Davis.js,它在可用时使用 pushState 在 JavaScript 中为您提供路由,而在没有 JavaScript 的情况下,它允许您的服务器端代码处理请求。

于 2011-02-04T20:25:10.787 回答
4

这是 railscasts 的 Ryan Bates 就该主题进行的精彩截屏。最后,如果 history.pushState 方法不可用,他只需禁用 ajax 功能:

http://railscasts.com/episodes/246-ajax-history-state

于 2012-01-03T16:50:14.963 回答
3

我在 History.js 之上编写了一个非常简单的路由器抽象,称为StateRouter.js。它处于开发的早期阶段,但我将它用作我正在编写的单页应用程序中的路由解决方案。和你一样,我发现 History.js 很难掌握,特别是因为我对 JavaScript 还很陌生,直到我明白你真的需要(或应该有)在它之上的路由抽象,因为它解决了低级问题。

这个简单的示例代码应该演示它是如何使用的:

var router = new staterouter.Router();
// Configure routes
router
  .route('/', getHome)
  .route('/persons', getPersons)
  .route('/persons/:id', getPerson);
// Perform routing of the current state
router.perform();

这是我为了展示它的用法而编造的一个小小提琴。

于 2013-01-02T20:10:20.377 回答
2

你可能想看看这个 jQuery 插件。他们的网站上有很多例子。http://www.asual.com/jquery/address/

于 2010-10-25T14:38:20.447 回答
1

如果 jQuery 可用,你可以使用jQuery BBQ

于 2010-10-25T14:40:57.093 回答