JavaScript如何实现无页面刷新修改URL地址
这个需求完全可以通过原生HTML5提供的History API实现,不需要任何框架,你参考的无刷新页面切换站点都是基于这套API做的。
核心原理
你之前代码里用window.location.href修改地址必然触发页面重载,要实现无刷新改URL,直接替换为History API提供的两个方法即可:
history.pushState():新增一条浏览器历史记录,用户点击后退按钮可以回到上一个URL状态,适合常规页面切换场景history.replaceState():替换当前历史记录,不会新增记录条目,适合不需要保留当前状态的场景
两个方法都不会触发页面刷新、不会触发资源重载,只会修改地址栏显示的URL。
现有代码问题修正
你的原有代码有几个明显问题需要先修复:
- 拼写错误:
doument.querySelector应为document.querySelector,示例域名拼写也存在笔误 - GET请求多余请求头:
setRequestHeader("Content-Type", "application/x-www-form-urlencoded")是POST表单提交用的,GET请求不需要设置,否则可能触发异常跨域预检 - 错误使用
window.location.href做跳转,这行是触发页面刷新的根源
具体实现代码
pushState接收三个参数:
- 状态对象:存储当前页面的自定义标识数据,供前进/后退事件触发时读取
- 标题参数:目前主流浏览器均未实际启用该参数,传空字符串即可
- 目标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
相关产品推荐
相关产品推荐

