如何在不重新渲染页面的情况下，实现浏览器地址栏URL动态变化

引言

最近勇哥在做一个 AI 对话应用🤖，也体验了不少 AI 对话应用。

在新对话场景下，当用户提交第一个问题后，大部分 AI 对话应用的处理方式是：前端生成一个唯一 ID，浏览器地址栏立即替换为用来标识该对话的 URL，类似 /chat/e797acdb-69a8-4aad-a1b3-91b6b9bcd839 这种。这样做的好处显而易见：唯一资源定位，生成的结果可以通过这个地址分享、再次访问，也为多轮对话做好了准备。

问题

因为勇哥在做技术选型的时候，选了基于 Next.js 的 ai-chatbot ，所以第一时间想到的用 Next.js 这把的 router.push() 来实现。经实践，这种方式行不通，网上很多信息是过时的，页面还是会刷新。

拿起 Next.js 这把锤子，什么问题都想当钉子去锤一下，学习了屠龙之术，却忽视了基本的劈砍撩拨的威力。

解决办法

很多问题最后都要返璞归真，用最朴素的食材。其实要想在不重新渲染页面的情况下，实现浏览器地址栏 URL 动态变化，只需要用基本的 Web API 中的 History API 下的 history.pushState() 或者 history.replaceState() 即可：

Copy
...
const newChatUrl = '/chat/' + uuid
window.history.pushState(window.history.state, '', newChatUrl);
...

基础巩固

理论向，较枯燥，如果解决了你的问题，可以关闭页面啦😎

window.history.replaceState 和 window.history.pushState 都是用于操作浏览器的历史记录栈的方法，但它们之间存在一些关键的区别：

window.history.pushState:

向浏览器的历史记录栈添加一个新的状态。

浏览器的地址栏会显示新的 URL，但不会触发页面的重新加载。

增加了一个新的历史记录条目，用户可以通过后退按钮返回到前一个页面。

window.history.replaceState:

替换当前的历史记录条目，而不是添加一个新的条目。

浏览器的地址栏会显示新的 URL，但不会触发页面的重新加载。

不增加新的历史记录条目，用户点击后退按钮会跳转到当前页面之前的历史记录。

示例

使用 pushState

Copy
window.history.pushState({ page: 1 }, "title 1", "/page1");

这会在历史记录中添加一个新的条目，用户可以通过后退按钮返回到之前的页面。

使用 replaceState

Copy
window.history.replaceState({ page: 2 }, "title 2", "/page2");

这会替换当前的历史记录条目，用户点击后退按钮会跳转到当前页面之前的历史记录。

总结

pushState 用于添加新的历史记录条目。

replaceState 用于替换当前的历史记录条目。

文中提到的资源：

ai-chatbot：https://github.com/vercel/ai-chatbot

history.pushState：https://developer.mozilla.org/zh-CN/docs/Web/API/History/pushState

history.replaceState：https://developer.mozilla.org/zh-CN/docs/Web/API/History/replaceState