文章目录
json
console.log('Intercepted Response:', JSON.stringify(response));
json
{
"data": {
"code": 0,
"msg": "成功",
"data": {
"id": 76,
"inviteCode": "957989",
"invitorId": 56,
"remark": "测试",
"generatedDate": "2025-01-08T16:55:27.163",
"expireTime": "2025-01-15T16:55:27.163",
"inviteLevel": 2,
"status": 0,
"boundPhone": null,
"weixinNickname": null,
"weixinHeadimg": null,
"boundWxUid": null,
"adminId": null,
"userId": null,
"isLocked": 0,
"createdDate": "2025-01-08T16:55:27.163",
"lastModifiedDate": "2025-01-08T16:55:27.163"
}
},
"status": 200,
"statusText": "",
"headers": {
"cache-control": "no-cache, no-store, max-age=0, must-revalidate",
"content-type": "application/json;charset=UTF-8",
"expires": "0",
"pragma": "no-cache"
},
"config": {
"url": "/api/invite-codes/generate",
"method": "post",
"params": {
"invitorId": 56,
"remark": "测试"
},
"headers": {
"Accept": "application/json, text/plain, */*",
"token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJhdWQiOiI1NiIsInJvbGUiOiJST0xFX0NPTVBBTllfU1VQRVIiLCJleHAiOjE3MzY0MDA5MDMsInVzZXJOYW1lIjoiMTg2NjE5Nzc1ODEiLCJ0eXBlIjoiYWRtaW4iLCJpYXQiOjE3MzYzMTQ1MDN9.OBFnxtoE4A2RO6gAcVm_CUkvJl_j6wpUkOPZOZySwEk"
},
"baseURL": "http://127.0.0.1:8087/",
"transformRequest": [null],
"transformResponse": [null],
"timeout": 0,
"withCredentials": false,
"xsrfCookieName": "XSRF-TOKEN",
"xsrfHeaderName": "X-XSRF-TOKEN",
"maxContentLength": -1
},
"request": {}
}
数据结构解释
data
: 包含实际业务响应数据,其中:code
: 响应码,0
表示成功。msg
: 响应消息。data
: 具体数据,包括邀请码的详细信息。
status
: HTTP 状态码,200
表示请求成功。headers
: 响应头信息。config
: 请求配置详情,包括 URL、请求方法、参数、头部信息等。request
: 请求对象,具体内容在此为空。
如需对其中的字段进行详细解析,请告知我! 😊
ts
// spid-admin/src/utils/request.ts
import axios from 'axios'
import { Message, MessageBox } from 'element-ui'
import { UserModule } from '@/store/modules/user'
import { api } from '@/utils/public-path'
let logoutCount:number = 0
const service = axios.create({
baseURL: api, // url = base url + request url
timeout: 0,
withCredentials: false // send cookies when cross-domain requests
})
// Request interceptors
service.interceptors.request.use(
(config) => {
// Add X-Access-Token header to every request, you can add other custom headers here
if (UserModule.token) {
const { token }: any = JSON.parse(UserModule.token)
config.headers['token'] = token
}
//console.log('Request config:', config); // 添加这行代码
return config
},
(error) => {
Promise.reject(error)
}
)
// Response interceptors
service.interceptors.response.use(
(response) => {
//console.log('Intercepted Response:', JSON.stringify(response));
//console.log('Full Response Data:', JSON.stringify(response, null, 2));
// Some example codes here:
// You can change this part for your own usage.
// status == 200: success
// code === 0: success
// code === 1: invalid access token
const res = response.data
if (res.code !== 0) {
if (res.code === 1) {
Message({
message: res.msg || 'Error',
type: 'warning',
duration: 5 * 1000
})
return response.data
} else if (res.code === 7) {
MessageBox.confirm(
'你已被登出,可以取消继续留在该页面,或者重新登录',
'确定登出',
{
confirmButtonText: '重新登录',
cancelButtonText: '取消',
type: 'warning'
}
).then(() => {
logoutCount = 0
localStorage.clear()
sessionStorage.clear()
UserModule.ResetToken()
location.reload() // To prevent bugs from vue-router
})
} else if (res.indexOf('form') !== -1) {
// 支付宝支付 ....... 为什么不改造成正常接口呢 不理解
return Promise.resolve(res)
} else {
Message({
message: res.msg || 'Error',
type: 'error',
duration: 5 * 1000
})
return Promise.reject(new Error(res.msg || 'Error'))
}
} else {
return response.data
}
},
(error) => {
console.log(error)
let errorInfo = error.response
let msg
if (!errorInfo) {
const { request: { statusText, status }, config } = JSON.parse(JSON.stringify(error))
errorInfo = {
statusText,
status,
request: { responseURL: config.url }
}
msg = status + ':' + errorInfo.statusText
} else {
if (error.response.data.code === -1) {
if (logoutCount === 0) {
MessageBox.confirm(
'你已被登出,可以取消继续留在该页面,或者重新登录',
'确定登出',
{
confirmButtonText: '重新登录',
cancelButtonText: '取消',
type: 'warning'
}
).then(() => {
logoutCount = 0
localStorage.clear()
sessionStorage.clear()
UserModule.ResetToken()
location.reload() // To prevent bugs from vue-router
msg = error.response.data.msg
})
logoutCount++
return
}
} else if (errorInfo.data.code === 1 || errorInfo.data.code === 2) {
msg = errorInfo.data.msg
} else {
msg = error.response.data.status + ':' + error.response.data.message
}
}
Message({
message: msg,
type: 'error',
duration: 5 * 1000
})
return Promise.reject(msg)
}
)
export default service
这段代码是一个基于 axios
的请求封装,主要用于处理 HTTP 请求的拦截和响应拦截。它结合了 Element UI
的消息提示和弹窗组件,实现了以下功能:
1. 核心功能
- 请求拦截 :
- 在请求发送之前,检查用户是否已登录(通过
UserModule.token
)。 - 如果用户已登录,将
token
添加到请求头中。
- 在请求发送之前,检查用户是否已登录(通过
- 响应拦截 :
- 对响应数据进行统一处理,根据返回的
code
值判断请求是否成功。 - 处理特定的错误码(如
code === 1
或code === 7
),并显示相应的提示信息。 - 在用户登录状态失效时,弹出确认框提示用户重新登录。
- 对响应数据进行统一处理,根据返回的
2. 代码结构分析
请求拦截器
typescript
service.interceptors.request.use(
(config) => {
if (UserModule.token) {
const { token }: any = JSON.parse(UserModule.token);
config.headers['token'] = token;
}
return config;
},
(error) => {
Promise.reject(error);
}
);
- 功能 :
- 在每次请求发送之前,检查用户是否已登录。
- 如果已登录,将
token
添加到请求头中。
- 注意 :
UserModule.token
是从 Vuex 模块中获取的,需要确保UserModule
已正确初始化。
响应拦截器
typescript
service.interceptors.response.use(
(response) => {
const res = response.data;
if (res.code !== 0) {
if (res.code === 1) {
Message({
message: res.msg || 'Error',
type: 'warning',
duration: 5 * 1000,
});
return response.data;
} else if (res.code === 7) {
MessageBox.confirm(
'你已被登出,可以取消继续留在该页面,或者重新登录',
'确定登出',
{
confirmButtonText: '重新登录',
cancelButtonText: '取消',
type: 'warning',
}
).then(() => {
logoutCount = 0;
localStorage.clear();
sessionStorage.clear();
UserModule.ResetToken();
location.reload(); // To prevent bugs from vue-router
});
} else if (res.indexOf('form') !== -1) {
// 支付宝支付 ....... 为什么不改造成正常接口呢 不理解
return Promise.resolve(res);
} else {
Message({
message: res.msg || 'Error',
type: 'error',
duration: 5 * 1000,
});
return Promise.reject(new Error(res.msg || 'Error'));
}
} else {
return response.data;
}
},
(error) => {
console.log(error);
let errorInfo = error.response;
let msg;
if (!errorInfo) {
const { request: { statusText, status }, config } = JSON.parse(JSON.stringify(error));
errorInfo = {
statusText,
status,
request: { responseURL: config.url },
};
msg = status + ':' + errorInfo.statusText;
} else {
if (error.response.data.code === -1) {
if (logoutCount === 0) {
MessageBox.confirm(
'你已被登出,可以取消继续留在该页面,或者重新登录',
'确定登出',
{
confirmButtonText: '重新登录',
cancelButtonText: '取消',
type: 'warning',
}
).then(() => {
logoutCount = 0;
localStorage.clear();
sessionStorage.clear();
UserModule.ResetToken();
location.reload(); // To prevent bugs from vue-router
msg = error.response.data.msg;
});
logoutCount++;
return;
}
} else if (errorInfo.data.code === 1 || errorInfo.data.code === 2) {
msg = errorInfo.data.msg;
} else {
msg = error.response.data.status + ':' + error.response.data.message;
}
}
Message({
message: msg,
type: 'error',
duration: 5 * 1000,
});
return Promise.reject(msg);
}
);
- 功能 :
- 对响应数据进行统一处理。
- 根据返回的
code
值判断请求是否成功,并显示相应的提示信息。 - 处理特定的错误码(如
code === 1
或code === 7
),并在用户登录状态失效时弹出确认框提示用户重新登录。
- 注意 :
code === 7
表示用户登录状态失效,会清除本地存储并刷新页面。code === 1
表示请求失败,会显示警告信息。- 其他错误码会显示错误信息。
3. 改进建议
- 支付宝支付逻辑 :
- 代码中提到
res.indexOf('form') !== -1
是处理支付宝支付的逻辑,但注释中提到"为什么不改造成正常接口呢 不理解"。建议将支付宝支付逻辑改造为标准的接口返回格式,以便统一处理。
- 代码中提到
- 错误处理 :
- 在
error.response
为空时,手动构造错误信息。可以考虑使用更健壮的方式处理网络错误。
- 在
logoutCount
的作用 :logoutCount
用于防止多次弹出登录失效的确认框。可以考虑使用更优雅的方式实现,例如在 Vuex 中维护登录状态。
4. 总结
这段代码是一个典型的 axios
请求封装,适用于需要统一处理请求和响应的场景。它结合了 Element UI
的消息提示和弹窗组件,提供了良好的用户体验。通过进一步优化错误处理和逻辑封装,可以提高代码的可维护性和健壮性。