解决:axios 请求头url传参数组时发生400错误

一、前言

  • axios封装的网络请求,url传参时,数组作为参数传递,发生400错误
  • 请求时数组参数url会保留 []

在这里插入图片描述

二、原因

RFC3986:除了 数字 + 字母 + -_.~ 不会被转义,其他字符都会被以百分号(%)后跟两位十六进制数 %{hex} 的方式进行转义

  • url 编码标准 RFC3986 是保留方括号的
  • 可能 axios 非最新版本也是一个原因,当前使用的"axios": "^1.7.2",据说最新版本是已经转换方括号了,没有试过…

三、解决方案

  • 一般 axios 自带 qs 模块,使用 qsparamsSerializer 方法序列化 params
  • 参考axios请求配置文档:https://www.axios-http.cn/docs/req_config
 // 解决数组url传参时参数带'[]'问题
 paramsSerializer: function (params) {
    return qs.stringify(params, { arrayFormat: "repeat" });
 },

在这里插入图片描述

  • 相关代码如下:

    1. 封装的axios文件request.js

      /**
       *
       * Author: ***
       * Date: 2024-09-04
       *
       * Description: axios接口封装
       *
       */
      
      import axios from "axios";
      import { Message } from "element-ui";
      
      // create an axios instance  创建 axios 实例
      const service = axios.create({
        baseURL: process.env.VUE_APP_BASE_API, // url = base url + request url
        timeout: 20000, // request timeout
        headers: {
          "Content-Type": "application/json;charset=UTF-8",
          "x-requested-with": "XMLHttpRequest",
        },
      });
      
      let globalVarMsg = null; // 全局变量Msg,用于控制Message只弹出一次
      
      /**
       * request interceptor 请求拦截
       */
      service.interceptors.request.use(
        (config) => {
          return config;
        },
        (error) => {
          // do something with request error
          return Promise.reject(error);
        }
      );
      /**
       * response interceptor 响应拦截
       */
      service.interceptors.response.use(
        (response) => {
          const status = response.status;
          const res = response.data;
          // if the custom code is not 20000, it is judged as an error.
          if (!res.success && response.config.headers.popUps !== false) {
            if (!globalVarMsg) {
              globalVarMsg = true;
              Message({
                message:
                  status != 200 ? "系统开小差,请稍后再试" : res.msg || "未知错误",
                type: "error",
                duration: 5 * 1000,
                onClose: () => {
                  globalVarMsg = null;
                },
              });
            }
          }
          return res;
        },
        (error) => {
          const msg = error.response?.data?.message || "";
          if (!globalVarMsg) {
            globalVarMsg = true;
            Message({
              message: msg || error.message || "系统开小差,请稍后再试",
              type: "error",
              duration: 5 * 1000,
              onClose: () => {
                globalVarMsg = null;
              },
            });
          }
          return Promise.reject(error);
        }
      );
      
      export default service;
      
      
    2. 接口文件 manage.js

      /**
       *   接口-管理
       */
      import request from "@/utils/request";       // 上面封装的request.js文件
      const qs = require("qs");                    // 一般 axios 自带 qs 模块
      
      const api = {
        delEvents: "/rest/event/batch/delete",
      };
      
      /**
       * 批量删除事件
       */
      export function delEvents(params) {
        return request({
          url: api.delEvents,
          method: "delete",
          params: params,
          // 解决数组url传参时参数带'[]'问题
          paramsSerializer: function (params) {
            return qs.stringify(params, { arrayFormat: "repeat" });
          },
        });
      }
      

四、qs 的常用 arrayFormat 参数

qs地址:https://github.com/ljharb/qs

qs镜像中文地址:https://gitcode.com/gh_mirrors/qs/qs/overview?utm_source=csdn_github_accelerator&isLogin=1

qs.stringify({ a: ['b', 'c', 'd'] });  

// 数组字符串化遵循 arrayFormat 选项,默认为 indices:
// 结果为 'a[0]=b&a[1]=c&a[2]=d'
qs.stringify({ a: ['b', 'c', 'd'] }, { indices: false });

// 结果为 'a=b&a=c&a=d'
qs.stringify({ a: ['b', 'c'] }, { arrayFormat: 'indices' })

// 结果为 'a[0]=b&a[1]=c'
qs.stringify({ a: ['b', 'c'] }, { arrayFormat: 'brackets' })

// 结果为 'a[]=b&a[]=c'
qs.stringify({ a: ['b', 'c'] }, { arrayFormat: 'repeat' })

// 结果为 'a=b&a=c'
qs.stringify({ a: ['b', 'c'] }, { arrayFormat: 'comma' })

// 结果为 'a=b,c'
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值