AJAX 页面 load/history.pushState 在离开网站后无法正常工作
AJAX page load/history.pushState not working properly after navigating off website
我的网站使用 XMLHttpRequests 在用户单击 link 时请求部分网页。
相关代码:
function requestPage(url, push) {
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
main.innerHTML = xhr.responseText;
attachLinkClickHandlers(main); // `main` = container element
if (push)
window.history.pushState(url, title, url);
}
};
xhr.open('GET', url);
xhr.setRequestHeader('Content-Only', 1); // Server responds to Content-Only header by not sending everything surrounding the main content.
xhr.send();
}
window.addEventListener('popstate', function (e) {
var page = e.state;
requestPage(page, false);
});
window.history.replaceState(location.href, document.title, location.href);
attachLinkClickHandlers(document);
在 link 上点击:
requestPage(link.href, true);
服务器响应示例:
正常请求响应:
<!doctype html>
<html>
<head>
...stuff...
</head>
<body>
...stuff...
<main>
<h1>Content</h1>
<p>Content Content</p>
</main>
...stuff...
</body>
</html>
响应 Content-Only
header 设置:
<h1>Content</h1>
<p>Content Content</p>
一切正常(页面加载,back/forward 按钮导航 在 站点内), 除了 ... 如果我点击一个 external link(没有附加点击处理程序,因为那将是跨源的)然后按下浏览器上的后退按钮,我是迎接 XHR 的响应 - 只是内容,没有 <html>
、<head>
或 <body>
标签,这意味着没有 CSS 或 JavaScript要么。
发生这种情况时如何让浏览器加载完整页面?
您是否使用相同的 URL 来检索两种不同类型的内容?
如果是这样,我遇到了完全相同的问题。我使用相同的 URL 和不同的请求 headers 到 return html 应用程序页面或一些 JSON 数据。在 history.pushState 调用和导航离开后,单击返回将导致 JSON 响应显示在浏览器中(因为这是与 URL 关联的浏览器缓存的最后响应)。
浏览器似乎只跟踪 URL 及其响应。使用 XHR 请求 headers 来指定您真正想要的内容类型是浏览器不会跟踪的。因此,当您离开然后 return 时,浏览器所拥有的只是 URL (可能还有缓存的响应)。
我的解决方法是改变 URLs,它实际上从那些用于修改浏览器历史记录的数据中获取 JSON 数据。
// on click of product item 123
var url = 'http://<webserver>/products/123',
title = 'Product 123';
history.pushState({
url: url,
title: title
}, title, url);
product = $.getJSON(url + '?json=1'); // make the url different
我整理了一些小测试来强调它是如何工作的https://github.com/robbishop/history-api-test
我已经在一些浏览器中尝试过,并注意到 Firefox(50.0 版)的工作方式与 Chrome 不同。例如,如果您修改页面内容,然后用假的 URL 调用 history.pushState,然后导航离开,然后单击返回。在 Chrome 中,您会得到一个 404 页面未找到(因为 URL 不是真实的),但在 Firefox 中,它实际上恢复了您上次看到的页面。所以浏览器也有一些差异,但我认为在直接操作浏览器历史记录
时,将 URLs 与单一内容类型相关联可能更安全
我的网站使用 XMLHttpRequests 在用户单击 link 时请求部分网页。
相关代码:
function requestPage(url, push) {
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
main.innerHTML = xhr.responseText;
attachLinkClickHandlers(main); // `main` = container element
if (push)
window.history.pushState(url, title, url);
}
};
xhr.open('GET', url);
xhr.setRequestHeader('Content-Only', 1); // Server responds to Content-Only header by not sending everything surrounding the main content.
xhr.send();
}
window.addEventListener('popstate', function (e) {
var page = e.state;
requestPage(page, false);
});
window.history.replaceState(location.href, document.title, location.href);
attachLinkClickHandlers(document);
在 link 上点击:
requestPage(link.href, true);
服务器响应示例:
正常请求响应:
<!doctype html>
<html>
<head>
...stuff...
</head>
<body>
...stuff...
<main>
<h1>Content</h1>
<p>Content Content</p>
</main>
...stuff...
</body>
</html>
响应 Content-Only
header 设置:
<h1>Content</h1>
<p>Content Content</p>
一切正常(页面加载,back/forward 按钮导航 在 站点内), 除了 ... 如果我点击一个 external link(没有附加点击处理程序,因为那将是跨源的)然后按下浏览器上的后退按钮,我是迎接 XHR 的响应 - 只是内容,没有 <html>
、<head>
或 <body>
标签,这意味着没有 CSS 或 JavaScript要么。
发生这种情况时如何让浏览器加载完整页面?
您是否使用相同的 URL 来检索两种不同类型的内容?
如果是这样,我遇到了完全相同的问题。我使用相同的 URL 和不同的请求 headers 到 return html 应用程序页面或一些 JSON 数据。在 history.pushState 调用和导航离开后,单击返回将导致 JSON 响应显示在浏览器中(因为这是与 URL 关联的浏览器缓存的最后响应)。
浏览器似乎只跟踪 URL 及其响应。使用 XHR 请求 headers 来指定您真正想要的内容类型是浏览器不会跟踪的。因此,当您离开然后 return 时,浏览器所拥有的只是 URL (可能还有缓存的响应)。
我的解决方法是改变 URLs,它实际上从那些用于修改浏览器历史记录的数据中获取 JSON 数据。
// on click of product item 123
var url = 'http://<webserver>/products/123',
title = 'Product 123';
history.pushState({
url: url,
title: title
}, title, url);
product = $.getJSON(url + '?json=1'); // make the url different
我整理了一些小测试来强调它是如何工作的https://github.com/robbishop/history-api-test
我已经在一些浏览器中尝试过,并注意到 Firefox(50.0 版)的工作方式与 Chrome 不同。例如,如果您修改页面内容,然后用假的 URL 调用 history.pushState,然后导航离开,然后单击返回。在 Chrome 中,您会得到一个 404 页面未找到(因为 URL 不是真实的),但在 Firefox 中,它实际上恢复了您上次看到的页面。所以浏览器也有一些差异,但我认为在直接操作浏览器历史记录
时,将 URLs 与单一内容类型相关联可能更安全