weixin_58412143 2024-05-08 09:56 采纳率: 91.6%
浏览 10
已结题

vue3在处理data.msg存在,覆盖默认提醒消息时请求拦截不起作用

有个请求接口返回code是422,里面有message但是不显示而是继续执行了.then回调,于是检查请求拦截,发现422被改成200,于是加上判断不让更改并且在422的时候弹出全局定义的消息$basemessage,然后再次请求接口的时候报错了

img

img

下面是请求拦截和调用接口代码

 let { proxy } = getCurrentInstance()
      const showMobile = () => {
        commonMobile({
          act: '查看手机',
          table_name: 'course_order_items',
          table_id: state.info.id,
        }).then((res) => {
          proxy.$baseAlert(res.mobile, '微信号', {
            confirmButtonText: '确定',
          })
        })
//request.js
import { useUserStore } from '@/store/modules/user'
import {
  baseURL,
  contentType,
  debounce,
  messageName,
  requestTimeout,
  statusName,
  successCode,
} from '@/config'
import qs from 'qs'
import router from '@/router'
import { isArray } from '@/utils/validate'
import { addErrorLog, needErrorLog } from '@vab/plugins/errorLog'
import { gp } from '@gp'
import {
    useStore
  } from 'vuex'

let loadingInstance: any

// 操作正常Code数组
const codeVerificationArray = isArray(successCode)
  ? [...successCode]
  : [...[successCode]]

const CODE_MESSAGE: any = {
  200: '服务器成功返回请求数据',
  404: '访问资源不存在',
  406: '请求格式不可得',
  410: '请求资源被永久删除,且不会被看到',
  500: '服务器发生错误',
}

/**
 * axios响应拦截器
 * @param config 请求配置
 * @param data response数据
 * @param status HTTP status
 * @param statusText HTTP status text
 * @returns {Promise<*|*>}
 */
const handleData = async ({ data, status, statusText }: any) => {
  const { resetAll } = useUserStore()
  if (loadingInstance) loadingInstance.close()
  // 若data.code存在,覆盖默认code
  let code = status
  // 若code属于操作正常code,则status修改为200
  if(code!=422){//new改动
    if (codeVerificationArray.indexOf(data[statusName]) + 1) code = 200
  }
  console.log(code)//没有问题-422
  switch (code) {
    case 200:
      // 业务层级错误处理,以下是假定restful有一套统一输出格式(指不管成功与否都有相应的数据格式)情况下进行处理
      // 例如响应内容:
      // 错误内容:{ code: 1, msg: '非法参数' }
      // 正确内容:{ code: 200, data: {  }, msg: '操作正常' }
      // return data
      return data
      //new
    case 422:
        console.log('4222222222',data,data[messageName])//ok
         // return Promise.reject(data[messageName])
         gp.$baseMessage(data.message, 'warning')
         console.log('--end--4222222222',data,data[messageName])//ok
    case 401:
      router.push({ path: '/login', replace: true }).then(() => {
        resetAll().then(() => {})
      })
      break
  }
  // 异常处理
  // 若data.msg存在,覆盖默认提醒消息
  const errMsg = `${
    data && data[messageName]
      ? data[messageName]
      : CODE_MESSAGE[code]
      ? CODE_MESSAGE[code]
      : statusText
  }`
  // 是否显示高亮错误(与errorHandler钩子触发逻辑一致)
 gp.$baseMessage(errMsg, 'error', 'vab-hey-message-error', false)
  if (needErrorLog())
    addErrorLog({ message: errMsg, stack: data, isRequest: true })
  return Promise.reject(data)
}

/**
 * @description axios初始化
 */
const instance = axios.create({
  baseURL,
  timeout: requestTimeout,
  headers: {
    'Content-Type': contentType,
  },
})

/**
 * @description axios请求拦截器
 */
instance.interceptors.request.use(
  (config: any) => {
    const userStore = useUserStore()
    const { token } = userStore

    // 不规范写法 可根据setting.config.js tokenName配置随意自定义headers
    // if (token) config.headers[tokenName] = token

    // 规范写法 不可随意自定义
    if (token) config.headers['Authorization'] = `Bearer ${token}`

    if (
      config.data &&
      config.headers['Content-Type'] ===
        'application/x-www-form-urlencoded;charset=UTF-8'
    )
      config.data = qs.stringify(config.data)
    if (debounce.some((item) => config.url.includes(item)))
      loadingInstance = gp.$baseLoading()
    return config
  },
  (error) => {
    return Promise.reject(error)
  }
)

/**
 * @description axios响应拦截器
 */
instance.interceptors.response.use(
  (response) => handleData(response),
  (error) => {
    const { response } = error
    if (response === undefined) {
      if (loadingInstance) loadingInstance.close()
      gp.$baseMessage(
        '连接后台接口失败,可能由以下原因造成:后端不支持跨域CORS、接口地址不存在、请求超时等,请联系管理员排查后端接口问题 ',
        'error',
        'vab-hey-message-error',
        false
      )
      return {}
    } else return handleData(response)
  }
)

export default instance
  • 写回答

4条回答 默认 最新

  • 专家-赤兔[在线] 全栈领域优质创作者 2024-05-08 09:59
    关注

    引自免费微信小程序:皆我百晓生

    看起来你在Vue 3项目中遇到的问题是关于axios请求拦截器的处理。当接收到HTTP状态码为422时,你尝试展示一个全局提示消息并终止后续的 .then 回调,但出现了错误。

    首先,让我们分析一下问题所在。你已经在handleData函数中处理了422状态码的情况,并且正确地打印了错误信息。然而,由于你之前对code变量的赋值逻辑有问题,导致了错误的发生。

    问题在于这里:

    if (code != 422) {
      if (codeVerificationArray.indexOf(data[statusName]) + 1) code = 200;
    }
    

    这行代码意味着只要不是422,且数据中的状态码在正常状态码数组里,就会将code设为200。因此,即使收到了422状态码,也会被强制改为200,导致后续的错误处理逻辑失效。

    要修复这个问题,你需要调整这个条件语句。正确的做法应该是先检查数据中的状态码是否为422,然后再决定如何处理。这里是修正后的代码:

    if (data[statusName] === 422) {
      console.log('4222222222', data, data[messageName]);
      gp.$baseMessage(data.message, 'warning');
      console.log('--end--4222222222', data, data[messageName]);
    
      // 返回一个新的错误对象,以便于在 .catch 中捕获和处理
      throw new Error(data.message);
    } else if (codeVerificationArray.indexOf(data[statusName]) + 1) {
      code = 200;
    }
    

    接下来,你需要确保在你的组件中处理这个异常。在showMobile函数中,你应该使用.catch来捕获并处理这个错误:

    let { proxy } = getCurrentInstance();
    const showMobile = async () => {
      try {
        await commonMobile({
          act: '查看手机',
          table_name: 'course_order_items',
          table_id: state.info.id,
        });
      } catch (err) {
        console.error('请求错误:', err.message); // 在这里处理错误消息
        proxy.$baseAlert(err.message, '警告', {
          confirmButtonText: '确定',
        });
      }
    };
    

    这样,在遇到422错误时,错误会被正确地捕获并在showMobile函数内部处理,而不是在全局的响应拦截器中处理。

    现在,你应该可以在请求失败时看到预期的全局提示消息,而不会抛出未捕获的错误。如果你还有其他问题或需要进一步的帮助,请随时告诉我。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论 编辑记录
查看更多回答(3条)

报告相同问题?

问题事件

  • 系统已结题 5月21日
  • 已采纳回答 5月13日
  • 创建了问题 5月8日

悬赏问题

  • ¥15 数据量少可以用MK趋势分析吗
  • ¥15 使用VH6501干扰RTR位,CANoe上显示的错误帧不足32个就进入bus off快慢恢复,为什么?
  • ¥15 大智慧怎么编写一个选股程序
  • ¥100 python 调用 cgps 命令获取 实时位置信息
  • ¥15 两台交换机分别是trunk接口和access接口为何无法通信,通信过程是如何?
  • ¥15 C语言使用vscode编码错误
  • ¥15 用KSV5转成本时,如何不生成那笔中间凭证
  • ¥20 ensp怎么配置让PC1和PC2通讯上
  • ¥50 有没有适合匹配类似图中的运动规律的图像处理算法
  • ¥15 dnat基础问题,本机发出,别人返回的包,不能命中