背景
最近遇到一个bug,跳转到某些页面后,浏览器地址栏url上面的query参数神秘消失,引起一些接口传参异常影响页面内容获取。Url从testUrl/user?userId=xxx变成了testUrl/user。
Bug出现前后涉及一个网络请求的代码,就像这样子:
ts- <script setup lang="ts">
- import axios from 'axios'
- import { getUrlParams } from './utils';
- const testHandler = () => {
- const params = getUrlParams()
- delete params.userId
- axios.post('testUrl', { ...params })
- }
- </script>
排查
先后经过了console.log大法和浏览器断点调试,仍然无法确定bug的原因,由于bug和url有关,猜测是不是因为有没有注意到的代码修改了url,于是在本地重写了hitsory的方法:
ts- const oldReplace = history.replaceState
- history.replaceState = function (..._arg) {
- console.trace()
- oldReplace.apply(this, _arg)
- }
- const oldPush = history.pushState
- history.pushState = function (..._arg) {
- console.trace()
- oldPush.apply(this, _arg)
- }
捕捉到调用栈:
- console.trace
- history.replacestate
- write
- ......
- useUrlSearchParams
- getUrlParams
- ......
可见是getUrlParams引起的:
ts- import { useUrlSearchParams } from "@vueuse/core"
- export const getUrlParams = (key: string) => {
- const params = useUrlSearchParams('history')
- return key ? params[key] : params
- }
也就是说,是VueUse的useUrlSearchParams方法重写了url,翻了一下它的文档(useUrlSearchParams | VueUse)和源码,发现useUrlSearchParams返回的是一个响应式对象,对象被修改了会同步到url上面:
js- function write(params, shouldUpdate) {
- pause();
- if (shouldUpdate)
- updateState(params);
- window.history.replaceState(
- window.history.state,
- window.document.title,
- window.location.pathname + constructQuery(params)
- );
- resume();
- }
- function onChanged() {
- if (!enableWrite)
- return;
- write(read(), true);
- }
修改参数对象触发onChanged,然后被write方法写到url上面。
解决
问题原因找到了,我们注意到enableWrite这个变量可以阻止重写url。看到:
js- function useUrlSearchParams(mode = "history", options = {}) {
- const {
- initialValue = {},
- removeNullishValues = true,
- removeFalsyValues = false,
- write: enableWrite = true,
- window = defaultWindow
- } = options;
- // ...
- }
这个getUrlParams工具方法是拿来获取url参数的,并没有用来修改过url,为了以后避免这种bug,把上面的write参数加上bug就修复了。
ts- useUrlSearchParams('history', { write: false })
小吐槽:看文档的时候write这个配置项好像不太显眼,只在Changelog上面有小小的一行
0 条评论未登录用户
Ctrl or + Enter 评论
