You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JavaScript如何实现无页面刷新修改URL地址

这个需求完全可以通过原生HTML5提供的History API实现,不需要任何框架,你参考的无刷新页面切换站点都是基于这套API做的。

核心原理

你之前代码里用window.location.href修改地址必然触发页面重载,要实现无刷新改URL,直接替换为History API提供的两个方法即可:

  • history.pushState():新增一条浏览器历史记录,用户点击后退按钮可以回到上一个URL状态,适合常规页面切换场景
  • history.replaceState():替换当前历史记录,不会新增记录条目,适合不需要保留当前状态的场景

两个方法都不会触发页面刷新、不会触发资源重载,只会修改地址栏显示的URL。

现有代码问题修正

你的原有代码有几个明显问题需要先修复:

  1. 拼写错误:doument.querySelector应为document.querySelector,示例域名拼写也存在笔误
  2. GET请求多余请求头:setRequestHeader("Content-Type", "application/x-www-form-urlencoded")是POST表单提交用的,GET请求不需要设置,否则可能触发异常跨域预检
  3. 错误使用window.location.href做跳转,这行是触发页面刷新的根源

具体实现代码

pushState接收三个参数:

  1. 状态对象:存储当前页面的自定义标识数据,供前进/后退事件触发时读取
  2. 标题参数:目前主流浏览器均未实际启用该参数,传空字符串即可
  3. 目标URL:必须和当前页面同源(同协议、同域名、同端口),否则浏览器会抛出跨域安全错误

修正后的核心逻辑代码如下:

// 抽离页面加载逻辑,方便多处复用
function loadPage(pageType, shouldPushState = true) {
    const xmld = new XMLHttpRequest();
    let apiPath = '';
    let targetPath = '';
    let stateData = {};

    // 匹配不同页面对应的接口和路由
    switch(pageType) {
        case 'search':
            apiPath = '/Api/SearchPage';
            targetPath = '/search';
            stateData = {page: 'search'};
            break;
        case 'home':
        default:
            apiPath = '/Api/HomePage';
            targetPath = '/home';
            stateData = {page: 'home'};
            break;
    }

    xmld.open("GET", apiPath, true);
    xmld.onreadystatechange = function() {
        if (xmld.readyState === 4 && xmld.status === 200) {
            const res = JSON.parse(xmld.responseText);
            if (res.Status === "Ok") {
                document.querySelector("#content").innerHTML = res.HTMLData;
                // 无刷新修改URL,前进后退场景不需要重复新增历史记录,用replaceState即可
                if (shouldPushState) {
                    window.history.pushState(stateData, '', targetPath);
                } else {
                    window.history.replaceState(stateData, '', targetPath);
                }
            }
        }
    }
    xmld.send();
}

// 给头部按钮绑定点击事件即可触发切换,示例:
// document.querySelector('#search-btn').addEventListener('click', () => loadPage('search'));
// document.querySelector('#home-btn').addEventListener('click', () => loadPage('home'));

// 监听浏览器前进/后退事件,保证URL变化时页面内容同步更新
window.addEventListener('popstate', function(e) {
    const currentPage = e.state?.page || 'home';
    // 触发对应页面加载,不需要新增历史记录
    loadPage(currentPage, false);
});

必要配套配置

要保证功能完整可用,你还需要做服务端适配:

  • 配置Web服务(Nginx/Apache)或PHP路由规则,将所有前端路径的请求都统一返回入口页面,避免用户直接访问/search这类路径、或者刷新页面时出现404错误
  • 接口返回的HTML片段要和对应页面的内容保持一致,避免直接访问URL和异步加载的内容出现差异

注意事项

  • 受浏览器安全策略限制,无法通过该API修改为跨域URL,否则会直接抛出错误
  • 不要在popstate触发的加载逻辑里重复调用pushState,否则会导致历史记录错乱
  • 如果需要兼容IE10及更早版本的浏览器,这套方案无法支持,但现代浏览器(包括移动端)都已全量兼容History API

内容的提问来源于stack exchange,提问作者Uttam Nath

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 00:18:23