我正在尝试使用 ajax 加载内容的 HTML5 历史 API。
我有一堆通过相对链接连接的测试页面。我有这个 JS,它处理对这些链接的点击。单击链接时,处理程序获取其 href 属性并将其传递给 ajaxLoadPage(),后者将来自请求页面的内容加载到当前页面的内容区域。(如果您正常请求,我的 PHP 页面设置为返回完整的 HTML 页面,但如果 ?fragment=true 附加到请求的 URL,则仅返回一部分内容。)
然后我的点击处理程序调用 history.pushState() 在地址栏中显示 URL 并将其添加到浏览器历史记录中。
$(document).ready(function(){
    var content = $('#content');
    var ajaxLoadPage = function (url) {
        console.log('Loading ' + url + ' fragment');
        content.load(url + '?fragment=true');
    }
    // Handle click event of all links with href not starting with http, https or #
    $('a').not('[href^=http], [href^=https], [href^=#]').on('click', function(e){
        e.preventDefault();
        var href = $(this).attr('href');
        ajaxLoadPage(href);
        history.pushState({page:href}, null, href);
    });
    // This mostly works - only problem is when popstate happens and state is null
    // e.g. when we try to go back to the initial page we loaded normally
    $(window).bind('popstate', function(event){
        console.log('Popstate');
        var state = event.originalEvent.state;
        console.log(state);
        if (state !== null) {
            if (state.page !== undefined) {
                ajaxLoadPage(state.page);
            }
        }
    });
});
当您使用 pushState 将 URL 添加到历史记录时,您还需要为 popstate 事件包含一个事件处理程序,以处理对后退或前进按钮的单击。(如果您不这样做,单击返回会在地址栏中显示您推送到历史记录的 URL,但页面未更新。)因此,我的 popstate 处理程序获取保存在我创建的每个条目的 state 属性中的 URL,并将其传递给 ajaxLoadPage 以加载适当的内容。
这适用于我的点击处理程序添加到历史记录的页面。但是当我“正常”请求浏览器添加到历史记录的页面时会发生什么?假设我正常登陆我的第一页,然后通过执行 ajax 加载的点击浏览我的网站 - 如果我然后尝试通过历史返回到该第一页,最后一次点击显示第一页的 URL,但没有'不在浏览器中加载页面。这是为什么?
我可以看出这与最后一个 popstate 事件的 state 属性有关。该事件的 state 属性为 null,因为只有通过 pushState() 或 replaceState() 添加到历史记录的条目才能为其赋值。但是我第一次加载页面是一个“正常”请求——为什么浏览器不只是退后一步并正常加载初始 URL?