修改AJAX应用中的地址栏URL以匹配当前状态

我正在编写一个AJAX应用程序,但随着用户在应用程序中移动,我希望尽管没有重新加载页面,地址栏中的URL也会更新。基本上,我希望他们能够在任何时候添加书签,从而返回到当前状态。

人们如何处理在AJAX应用程序中保持RESTfulness?

0
额外 编辑
意见: 3
我编辑了答案,使pushState方法突出。
额外 作者 jasonjwwilliams,
<�代码> window.history.pushState(NULL, '喜', '第1页?ID = 32')</代码>
额外 作者 Omu,
它用于维护您的应用程序的状态,但与“RESTfulness”无关。
额外 作者 Mohamed,
接受的答案是在5年前写的,与此同时,我们得到了window.history.pushState,就像@Omu所说的那样。 location.hash带来了许多问题,最好避免它。
额外 作者 peteroak,

6 答案

做到这一点的方法是在AJAX更新导致状态更改时操作 location.hash ,以便您希望有一个谨慎的URL。例如,如果您的网页的网址为:

http://example.com/

如果客户端函数执行了此代码:

// AJAX code to display the "foo" state goes here.

location.hash = 'foo';

然后,浏览器中显示的URL将更新为:

http://example.com/#foo

这允许用户书签的“富”状态的页面,并使用浏览器的历史状态之间进行导航。

有了这个机制,您就需要使用JavaScript解析出客户端URL的哈希部分,以创建并显示适当的初始状态,因为片段标识符(#之后的部分)不会发送到服务器。

Ben Alman's hashchange plugin makes the latter a breeze if you're using jQuery.

0
额外
@buymeasoda感谢编辑;我不确定当我写这部分时我在想什么。
额外 作者 Dave Ward,
@Neil:我当时有意使用/ questions / page结构,但我不完全确定原因。你可能是正确的,保持简单更清晰。我相应地更新了答案。
额外 作者 Dave Ward,
@Pascal你可以,但只能在支持HTML5的pushState的浏览器中使用。关于这方面的好消息: diveintohtml5.info/history.html
额外 作者 Dave Ward,
看起来你是对的。这是唯一的方法。这似乎是对您建议的一个很好的详细解释:<< a href =“http://ajaxpatterns.org/Unique_URLs>”rel =“nofollow noreferrer”> ajaxpatterns.org/Unique_URLs> ;
额外 作者 jasonjwwilliams,
哇,这个答案非常有帮助。尽管URL示例有点令人困惑,但SO可能会自动替换标题链接。如何用example.com和example.com/#foo之类的东西替换它们,以便我们能够以明文形式查看整个网址。
额外 作者 Neil,
我最终成为history.js的粉丝,以覆盖浏览器兼容性的基础 github.com/andreasbernhard /history.js
额外 作者 jocull,
@Dave我想#foo没有哈希字符是可能的?
额外 作者 Pascal,

如果OP或其他人仍在寻找一种方法来修改浏览器历史记录以启用状态,那么按照IESUS的建议,使用pushState和replaceState是现在执行此操作的“正确”方法。它比location.hash的主要优势在于它可以创建实际的URL,而不仅仅是哈希。如果保存了使用哈希的浏览器历史记录,然后在JavaScript禁用的情况下重新访问,则应用程序将无法工作,因为哈希不会发送到服务器。但是,如果已使用pushState,则整个路由将发送到服务器,然后您可以构建该服务器以适当地响应路由。我看到一个例子,在服务器和客户端都使用相同的胡须模板。如果客户端启用了javascript,他会避免往返服务器的响应,但应用程序在没有javascript的情况下工作得很好。因此,在没有javascript的情况下,该应用可以优雅地降级。

另外,我相信有一些框架,像history.js这样的名字。对于支持HTML5的浏览器,它使用pushState,但如果浏览器不支持,它会自动回退到使用散列。

0
额外

这与凯文所说的相似。你可以让你的客户端状态为一些JavaScript对象,当你想保存状态时,你可以序列化对象(使用JSON和base64编码)。然后可以将href的片段设置为该字符串。

var encodedState = base64(json(state));
var newLocation = oldLocationWithoutFragment + "#" + encodedState;

document.location = newLocation; // adds new entry in browser history
document.location.replace(newLocation); // replaces current entry in browser history

第一种方式将新状态视为新的位置(所以后退按钮将把他们带到先前的位置)。后者不。

0
额外
做document.location.replace也会将浏览器重定向到该URL(只是在Chrome控制台中试过)
额外 作者 Omu,
有没有办法添加一个条目到书签历史记录而不刷新页面?设置位置(如第一个示例中所示)将导致刷新,不是吗?
额外 作者 Drew Noakes,

检查用户是否在页面中,当你点击url栏时,javascript说你已经失去了网页。 如果您更改网址栏,然后按下'ENTER'并用符号'#'在其中,然后再次进入该页面,而无需用鼠标手动点击该页面,然后从javascript中输入keyboad事件命令(document.onkeypress)能够检查它是否进入并激活重定向的JavaScript。 你可以检查用户是否在window.onfocus页面,并检查他是否与window.onblur在一起。

是的,这是可能的。

;)

0
额外
当用户使用#符号编辑url栏时,这是我看到优雅的方式来更改页面。
额外 作者 Marcelo,

看看像book.cakephp.org这样的网站。此网站不使用散列而使用AJAX更改网址。我不确定它是如何做到的,但我一直在努力弄清楚。如果有人知道,请告诉我。

另外github.com在某个项目中查看导航时。

0
额外
我注意到在GitHub大约一周前。他们究竟是怎么做到的?必须回去检查。
额外 作者 Drew Noakes,
感谢你,这正是我所期待的。我想知道github是如何做到的。起初我以为它必须重新加载,但只有AJAX请求。在Opera中,它重新加载了页面。
额外 作者 kamranicus,
fb在浏览不同组的页面时使用了类似的技术。您有一个左侧导航栏,其中提到了不同的群组。当你点击一个特定的组名称时,URL会发生变化,只有主内容窗格的内容会随着URL(无散列)而变化。所以当用户重新加载页面时,他们不会被重定向到主页,而是被重定向到组的页面。
额外 作者 Madeyedexter,
他们似乎在使用javascript函数pushState()。这增加了你的浏览器的历史。了解更多;它非常有趣和酷。
额外 作者 daniel.wright,

在使用Ajax时,作者不太可能重新加载或重定向访问者。 但为什么不使用HTML5的 pushState / replaceState

You'll be able to modify the addressbar as much as you like. Get natural looking urls, with AJAX.

Check out the code on my latest project: http://iesus.se/

0
额外