使用 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 API 和 Location 对象剖析