我正在开发一个 Vue.js 应用程序,使用 Vue Router 和 Axios 来获取用户数据。我有两个页面:/dashboard 和 /dashboard/me。即使刷新后,/dashboard 页面的数据也已成功加载并显示。但是,当我导航到 /dashboard/me 并刷新页面时,我丢失了 Dashboard 组件中的数据(Dashboard 是所有子路由的包装器),并且请求导致 304 Not Modified 状态代码。
这是我尝试过的:
Vue Router 设置:路由定义如下:
const routes: RouteRecordRaw[] = [
{
path: '/dashboard', component: Dashboard, name: 'dashboard',
children: [{ path: 'me', name: 'me', component: AboutMePage }],
},
];
我最初将 me 路由定义为路径:'me'(相对),但是当我将其更改为路径:'/me'(绝对)时,页面在刷新时可以正常工作,但问题是现在路由变成/dashboard 和 /me 而不是 /dashboard/me。
Axios请求:我正在使用Axios来获取数据,它在/dashboard路由上运行良好。然而,在 /dashboard/me 路由上,当我刷新页面时,我收到 304 Not Modified 响应,这会导致数据丢失。
请求代码如下:
const { data, isLoading, refetch } = useGetUserQuery(userId, {
onSuccess: (user) => {
toast.add({
severity: 'success',
summary: `Welcome, ${user.email}`,
life: 3000,
});
},
onError: (error) => {
toast.add({
severity: 'error',
summary: error?.message[0],
life: 3000,
});
},
});
onst useGetUserQuery = (userId: string, callbacks: { onSuccess?: (response: IUser) => void; onError?: (error: Error) => void }) => {
const userQuery = useQuery<IUser, Error>({
queryKey: ['user', userId],
queryFn: () => UserService.getUserById(userId),
// retry: 0,
// staleTime: 0,
// cacheTime: 0,
enabled: !!userId, // Only fetch if userId is available
});
// Attach onSuccess and onError handlers
useQueryEvents(userQuery, callbacks);
return userQuery;
};
class UserService {
static async getUserById(id: string): Promise<IUser> {
try {
const { data } = await axiosInstance.get(`/users/${id}`, { authRequired: true } as CustomAxiosRequestConfig)
return data
} catch (error) {
if (error instanceof AxiosError) {
throw error.response?.data;
} else {
throw new Error('An unexpected error occurred');
}
}
}
}
export const axiosInstance: AxiosInstance = axios.create({
baseURL: 'v1/',
timeout: 1000,
headers: {
'Content-Type': 'application/json',
'Cache-Control': 'no-cache', // Disable cache
// 'Pragma': 'no-cache', // HTTP 1.0 compatibility
// 'Expires': '0', // Ensures cache is expired
}
})
refetch函数也是用来刷新数据的。
Vite 中的代理配置:我在 vite.config.ts 文件中配置了代理,以将请求重定向到后端服务器。
export default defineConfig({
plugins: [vue()],
server: {
proxy: {
'/v1': {
target: 'http://localhost:3001/',
changeOrigin: true,
secure: false,
ws: true,
configure: (proxy, _options) => {
proxy.on('error', (err, _req, _res) => {
console.log('proxy error', err);
});
proxy.on('proxyReq', (proxyReq, req, _res) => {
console.log('Sending Request to the Target:', req.method, req.url);
});
proxy.on('proxyRes', (proxyRes, req, _res) => {
console.log('Received Response from the Target:', proxyRes.statusCode, req.url);
});
},
}
}
}
})
当我刷新 /dashboard/me 页面时,我得到空响应并且数据丢失。
网络响应显示 304 Not Modified,但在 /dashboard 页面上,它工作正常,我得到了正确的数据。
我尝试过的:
将路由路径从相对路径(“me”)更改为绝对路径(“/me”),这使得页面可以正常工作,但破坏了 URL 结构。
在 Axios 中使用 Cache-Control: no-cache 标头,但仍然收到 304 响应。
清除浏览器缓存并在隐身模式下测试,问题依然存在。
问题:
为什么更改路由路径('me' 到 '/me')会影响数据获取的行为?
为什么 /dashboard 请求正常,但 /dashboard/me 页面刷新时数据丢失?
如何解决该问题并确保始终获取新数据而不更改 URL 结构?
任何帮助将不胜感激!
请求在顶级路由上发出时有效,但在带有 HTML 响应的嵌套路由上失败,这表明可能的原因是向错误的 URL 发出了请求,并且未对此进行调试。
对于使用相对 URL 进行请求且未正确设置的应用程序来说,这是一个常见问题
<base>
。
实际上从来不希望向相对路径发出 API 请求。由于使用了axios,所以应该是
baseURL: '/v1/
而不是baseURL: 'v1/
。