【问题标题】:AJAX page load/history.pushState not working properly after navigating off website离开网站后 AJAX 页面加载/history.pushState 无法正常工作
【发布时间】:2016-10-18 19:39:50
【问题描述】:

我有一个网站,当用户单击链接时,它使用 XMLHttpRequests 请求部分网页。

相关代码:

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);

点击链接:

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 标头集的响应:

<h1>Content</h1>
<p>Content Content</p>

一切都按预期工作(页面加载、后退/前进按钮导航网站内),除了...如果我点击一个外部 em> 链接(点击处理程序未附加到该链接,因为那将是跨源的),然后按浏览器上的后退按钮,我很高兴 XHR 的响应是什么 - 只是内容,没有 @ 987654326@、&lt;head&gt;&lt;body&gt; 标签,这意味着也没有 CSS 或 JavaScript。

发生这种情况时如何让浏览器加载完整页面?

【问题讨论】:

    标签: javascript ajax http-headers xmlhttprequest html5-history


    【解决方案1】:

    您是否使用同一个 URL 来检索两种不同类型的内容?

    如果是这样,我遇到了完全相同的问题。我使用相同的 URL 和不同的请求标头来返回 html 应用程序页面或一些 JSON 数据。在调用 history.pushState 并导航离开后,点击返回将导致 JSON 响应显示在浏览器中(因为这是浏览器缓存与 URL 关联的最后一个响应)。

    浏览器似乎只跟踪 URL 及其响应。使用 XHR 请求标头来指定您实际需要的内容类型不是浏览器跟踪的内容。因此,当您离开并返回浏览器时,浏览器所拥有的只是 URL(可能还有缓存的响应)。

    我的解决方法是更改​​从用于修改浏览器历史记录的 URL 中实际获取 JSON 数据的 URL。

    // 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 中,它实际上会恢复您上次看到的页面。所以浏览器也存在一些差异,但我认为在直接操作浏览器历史记录时,将 URL 与单一内容类型相关联可能更安全

    【讨论】:

    • 这是一个奇怪的现象...谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-08-03
    • 1970-01-01
    • 1970-01-01
    • 2016-09-14
    • 2017-01-30
    • 2018-10-13
    • 1970-01-01
    相关资源
    最近更新 更多