|
|
@@ -1,4 +1,4 @@
|
|
|
-import axios from 'axios' // 引入axios
|
|
|
+import axios, { AxiosHeaders } from 'axios' // 引入axios
|
|
|
import { ElMessage, ElMessageBox } from 'element-plus'
|
|
|
import { useUserStore } from '@/pinia/modules/user'
|
|
|
import { emitter } from '@/utils/bus.js'
|
|
|
@@ -36,11 +36,26 @@ service.interceptors.request.use(
|
|
|
showLoading()
|
|
|
}
|
|
|
const userStore = useUserStore()
|
|
|
- config.headers = {
|
|
|
- 'Content-Type': 'application/json',
|
|
|
+ const baseHeaders = {
|
|
|
'x-token': userStore.token,
|
|
|
- 'x-user-id': userStore.userInfo.ID,
|
|
|
- ...config.headers
|
|
|
+ }
|
|
|
+ const uid = userStore.userInfo?.ID
|
|
|
+ if (uid !== undefined && uid !== null && uid !== '') {
|
|
|
+ baseHeaders['x-user-id'] = uid
|
|
|
+ }
|
|
|
+ if (typeof FormData !== 'undefined' && config.data instanceof FormData) {
|
|
|
+ // Axios 1.x 的 config.headers 多为 AxiosHeaders,用对象展开合并会删不掉 Content-Type,
|
|
|
+ // 请求仍带 application/json,服务端无法按 multipart 解析 file 与表单字段。
|
|
|
+ const merged = AxiosHeaders.from(baseHeaders).concat(config.headers)
|
|
|
+ merged.delete('Content-Type')
|
|
|
+ merged.delete('content-type')
|
|
|
+ config.headers = merged
|
|
|
+ } else {
|
|
|
+ config.headers = {
|
|
|
+ 'Content-Type': 'application/json',
|
|
|
+ ...baseHeaders,
|
|
|
+ ...config.headers,
|
|
|
+ }
|
|
|
}
|
|
|
return config
|
|
|
},
|
|
|
@@ -67,6 +82,28 @@ service.interceptors.response.use(
|
|
|
if (response.headers['new-token']) {
|
|
|
userStore.setToken(response.headers['new-token'])
|
|
|
}
|
|
|
+ // PHP 调试用 echo/print_r 时多为 text/html,axios 得到的是字符串,没有 .code;
|
|
|
+ // 若 Content-Type 不是 application/json,先尝试把字符串当 JSON 解析,否则提示去 Network→响应 看原文。
|
|
|
+ if (typeof response.data === 'string' && response.status === 200) {
|
|
|
+ const ct = String(response.headers['content-type'] || response.headers['Content-Type'] || '')
|
|
|
+ if (!/application\/json/i.test(ct)) {
|
|
|
+ const raw = response.data
|
|
|
+ const trimmed = raw.trimStart()
|
|
|
+ if (trimmed.startsWith('{') || trimmed.startsWith('[')) {
|
|
|
+ try {
|
|
|
+ response.data = JSON.parse(raw)
|
|
|
+ } catch {
|
|
|
+ // 非合法 JSON,按调试输出处理
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (typeof response.data === 'string') {
|
|
|
+ if (import.meta.env.DEV) {
|
|
|
+ console.warn('[接口返回非 JSON,多为调试输出]', response.config?.url, '\n', raw.slice(0, 12000))
|
|
|
+ }
|
|
|
+ return { code: -1, msg: '非 JSON 响应' }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
if (response.data.code === 0 || response.headers.success === 'true') {
|
|
|
if (response.headers.msg) {
|
|
|
response.data.msg = decodeURI(response.headers.msg)
|
|
|
@@ -83,7 +120,8 @@ service.interceptors.response.use(
|
|
|
localStorage.clear()
|
|
|
router.push({ name: 'Login', replace: true })
|
|
|
}
|
|
|
- return response.data.msg ? response.data : response
|
|
|
+ // 必须始终返回 response.data,否则调用方拿到的是 Axios 整包,res.code 为 undefined,会误判成「导入失败」
|
|
|
+ return response.data
|
|
|
}
|
|
|
},
|
|
|
error => {
|
|
|
@@ -139,7 +177,7 @@ service.interceptors.response.use(
|
|
|
break
|
|
|
}
|
|
|
|
|
|
- return error
|
|
|
+ return Promise.reject(error)
|
|
|
}
|
|
|
)
|
|
|
export default service
|