响应拦截器
既然后端有统一响应格式,那么前端也应该有与之对应的部分,那就是响应拦截器。
响应拦截器 (Response Interceptor) 是 HTTP 客户端库(例如 Axios、Fetch API 的封装等)提供的一种机制,它允许你在 HTTP 响应到达你的应用程序代码之前,对其进行统一的处理或修改。
可以把它想象成一个“门卫”或者“处理器”,所有从服务器返回的 HTTP 响应,在被你的 then() 或 await 接收到之前,都要先经过它。
Result 接口
在编写响应拦截器之前,先写一个Result接口
在src中创建一个interface文件夹,然后在interface中创建一个index.ts
export interface Result<T = any> { code: number, msg: string, data?: T}这是一个接口,和后端的统一响应格式对应。
响应拦截器
我们来到前端的Api下的index.ts, 添加如下代码:
api.interceptors.response.use( response => { const res: Result = response.data
// 如果 code 不是 200,表示业务失败 if (res.code !== 200) { console.error(`后端错误: ${res.msg}`); // 返回一个被拒绝的 Promise,携带自定义的错误信息 return Promise.reject(new Error(res.msg)) } else { return res.data } }, error => { // 处理 HTTP 状态码层面的错误 (例如 404, 500 等) console.error('HTTP 请求错误:', error) return Promise.reject(error) })LoginResponse接口
后端将数据都封装在了LoginResponseDto里,那么前端也要有对应的LoginResponse接口,
我们在上文创建的interface文件夹中,创建一个User.ts 代码如下:
interface User { id: number, username: string,}
export interface saToken { tokenName: string, tokenValue: string, isLogin: boolean, loginId: string, loginType: string, tokenTimeout: number, sessionTimeout: number, tokenSessionTimeout: number, tokenActiveTimeout: number, loginDeviceType: string, tag?: string}
interface LoginResponse { user: User, saToken: saToken}
export type { User, LoginResponse}接下来修改一下登录的api,打开api文件夹下的Api.ts 修改登录api,代码如下:
function login(username: string, password: string) { return api.post<Result<any>, LoginResponse>('/user/login', { username, password })}在post方法后添加泛型Result<any>和LoginResponse
它表示 api.post 这个 Axios 请求,从后端接收到的原始数据结构(也就是 response.data)将会是 Result 类型,并且这个 Result 的 data 字段里包含的实际数据类型是 LoginResponse。 这样写可以告诉编译器和阅读代码的人,这个部分是用来处理什么类型的数据的。 编译器也会给出相应的补全,在后续编写代码时。
完善前端登录注册逻辑
之前只简单模拟了一下登录注册,现在开始正式完善。
登录
打开你的Login.vue
更改你的登录方法handleLogin
const handleLogin = async () => { try { if (!loginFormRef.value) { ElMessage.error("表单引用未就绪") return } // 验证表单 const valid = await loginFormRef.value.validate() if (!valid) return
loading.value = true
// 这里替换为实际的登录API调用 const loginResult = await login(loginForm.username, loginForm.password) const user = loginResult.user const saToken = loginResult.saToken localStorage.setItem('curUser', JSON.stringify(user)) localStorage.setItem('token', JSON.stringify(saToken))
ElMessage.success("登录成功") router.push('/') } catch (error: any) { ElMessage.error(error.message || '登录失败') } finally { loading.value = false }}注册
打开你的Register.vue
更改你的注册方法handleRegister
const handleRegister = async () => { try { if (!registerFormRef.value) { ElMessage.error("表单引用未就绪") return } // 验证表单 const valid = await registerFormRef.value.validate() if (!valid) return
loading.value = true
await register(registerForm.username, registerForm.password)
router.push('/login') } catch (error: any) { ElMessage.error(error.message || '注册失败') } finally { loading.value = false }}流程图
如果这篇文章对你有帮助,欢迎分享给更多人!
部分信息可能已经过时









