liuhairui пре 2 недеља
родитељ
комит
7f144a8df8
1 измењених фајлова са 45 додато и 7 уклоњено
  1. 45 7
      src/utils/request.js

+ 45 - 7
src/utils/request.js

@@ -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