使用 HTML5 History API 的好教程(Pushstate?)[关闭]

Posted

技术标签:

【中文标题】使用 HTML5 History API 的好教程(Pushstate?)[关闭]【英文标题】:Good tutorial for using HTML5 History API (Pushstate?) [closed] 【发布时间】:2011-04-30 06:13:54 【问题描述】:

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

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

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

http://html5demos.com/history

【问题讨论】:

【参考方案1】:

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

【讨论】:

再次,当 JS 关闭时,此解决方案似乎失败。我认为 history API 有能力与 modrewrite 一起工作,这样链接总是由服务器在第一个实例中处理,而不需要从 JS 层重定向。 你在 modrewrite 的正确轨道上。管理历史 API 和处理用户没有 JS 时的解决方案实际上是两个独立的事情。如果您没有 JS,则必须使用标准 href 和服务器响应来处理用户。如果用户的浏览器支持,历史 API 可以构建为“很高兴拥有”。 在禁用 javascript 时,jQuery Address 1.3 附带的 Express 和 State 示例都可以正常工作。第二个使用 php 和 mod_rewrite。 正是我的机智。我打算在没有 JS 的情况下构建站点,添加 AJAX 元素,然后使用历史记录重写 URL,保留深度链接。从理论上讲,它应该是比我见过的任何方法更好的方法,因为该网站在任何阶段都不会依赖 AJAX -1 因为 jQuery Address 不是 HTML5 State API 的直接端口 - 不支持数据或标题,以及 replaceState。【参考方案2】:

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

【讨论】:

这似乎在关闭 JS 时失败。 这可能是真的——还没有调查过。我认为所有基于 js 库的方法都会遇到这个问题。它们基于操纵 url 的哈希部分。 这就是 HTML5 History API 的重点——doesn't break anything @MildFuzz 计算机似乎在没有电源的情况下出现故障!我认为你有一个 ID-10-T 错误... 讽刺的是,是你误会了【参考方案3】:

要想获得精彩的教程,您只需要有关此功能的 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

【讨论】:

无耻的自插。优秀的帖子和插件虽然。 :)【参考方案4】:

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

【讨论】:

【参考方案5】:

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

【讨论】:

确实是优秀的教程。同时 URL 变成了diveintohtml5.info;可能想更新答案。【参考方案6】:

这里是 railscasts 的 Ryan Bates 关于该主题的精彩截屏视频。最后,如果 history.pushState 方法不可用,他会简单地禁用 ajax 功能:

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

【讨论】:

【参考方案7】:

请记住,在使用 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;

【讨论】:

这才是真正的答案。这在 Balupton 的 History.js wiki/tutorials 等上是没有的。事实上,History.js 不使用哈希,所以你需要使用 .htaccess 重定向! 理想情况下,您的服务器/应用程序应该适当地响应路由,而无需重写。 同意,除了许多现代 JavaScript 框架,如 Backbone.js、Spine、Ember 等。这些本质上都是“一页”JavaScript 应用程序。人们可以制定出一种为 SEO 等提供写后端模板的解决方案,但与此同时,这将是必要的。 *正确。我在这里更详细地写了这个:readystate4.com/2012/05/17/…【参考方案8】:

我在 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();

这是我编造的一个小fiddle,以展示它的用法。

【讨论】:

这个小提琴在 Mac 上的 Chrome 中不适合我。它抛出一个错误。 (Uncaught ReferenceError: staterouter is not defined) @DrewT 谢谢,由于 github.com 的更改,小提琴坏了,但我已经解决了。 是的,正在工作,感谢您的快速响应。【参考方案9】:

HTML5 history spec 很古怪。

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)(后一页)和history.go(1)(前一页)调度popstate事件。

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

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

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

【讨论】:

只有我,还是new PopStateEvent(...)似乎在IE11中不起作用?有没有人知道的解决方法? 看起来 IE 11 需要类似:var pop_state_event = document.createEvent('Event'); pop_state_event.initEvent('popstate', true, true); window.dispatchEvent(pop_state_event);

以上是关于使用 HTML5 History API 的好教程(Pushstate?)[关闭]的主要内容,如果未能解决你的问题,请参考以下文章

HTML5 history详解

HTML5学习笔记之History API

HTML5 History API 和 Location 对象剖析

HTML5 history API与ajax分页实例页面

HTML5历史状态管理history API-pushState/replaceState与popstate事件

HTML5历史状态管理history API-pushState/replaceState与popstate事件