解决: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'
相关推荐
非凡ghost15 分钟前
WinMute(自动锁屏静音软件) 中文绿色版
前端·javascript·后端
7ayl35 分钟前
Vue3 - Reactivity的核心流程
前端·vue.js
The 旺36 分钟前
【AI编程实战】零基础用ChatGPT+Cursor开发完整Web应用:30分钟从idea到上线
前端·chatgpt·ai编程
sulikey1 小时前
Qt 入门简洁笔记:信号与槽
前端·c++·笔记·qt·前端框架·1024程序员节·qt框架
袁煦丞1 小时前
安卓旧机变服务器,KSWEB部署Typecho博客并实现远程访问:cpolar内网穿透实验室第645个成功挑战
前端·程序员·远程工作
爱抽烟的大liu1 小时前
iOS进阶1-combine
前端
俩毛豆1 小时前
【图片】【编缉】图片增加水印(通过组件的Overlay方法增加水印)
前端·harmonyos
gustt1 小时前
JS 变量那些坑:从 var 到 let/const 的终极解密
前端·javascript
出师未捷的小白1 小时前
[NestJS] 手摸手~工作队列模式的邮件模块解析以及grpc调用
前端·后端
Z_B_L1 小时前
问题记录--elementui中el-form初始化表单resetFields()方法使用时出现的问题
前端·javascript·vue.js·elementui·1024程序员节