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

一、前言

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

二、原因

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

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

三、解决方案

javascript 复制代码
 // 解决数组url传参时参数带'[]'问题
 paramsSerializer: function (params) {
    return qs.stringify(params, { arrayFormat: "repeat" });
 },
  • 相关代码如下:

    1. 封装的axios文件request.js

      javascript 复制代码
      /**
       *
       * 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

      javascript 复制代码
      /**
       *   接口-管理
       */
      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

javascript 复制代码
qs.stringify({ a: ['b', 'c', 'd'] });  

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

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

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

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

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

// 结果为 'a=b,c'
相关推荐
百万蹄蹄向前冲1 小时前
Trae分析Phaser.js游戏《洋葱头捡星星》
前端·游戏开发·trae
朝阳5812 小时前
在浏览器端使用 xml2js 遇到的报错及解决方法
前端
GIS之路2 小时前
GeoTools 读取影像元数据
前端
ssshooter3 小时前
VSCode 自带的 TS 版本可能跟项目TS 版本不一样
前端·面试·typescript
Jerry3 小时前
Jetpack Compose 中的状态
前端
dae bal4 小时前
关于RSA和AES加密
前端·vue.js
柳杉4 小时前
使用three.js搭建3d隧道监测-2
前端·javascript·数据可视化
lynn8570_blog4 小时前
低端设备加载webp ANR
前端·算法
LKAI.5 小时前
传统方式部署(RuoYi-Cloud)微服务
java·linux·前端·后端·微服务·node.js·ruoyi
刺客-Andy5 小时前
React 第七十节 Router中matchRoutes的使用详解及注意事项
前端·javascript·react.js