解决: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'
相关推荐
还有你Y4 小时前
Shell 脚本语法
前端·语法·sh
踩着两条虫6 小时前
如何评价VTJ.PRO?
前端·架构·ai编程
Mh7 小时前
鼠标跟随倾斜动效
前端·css·vue.js
小码哥_常8 小时前
Kotlin类型魔法:Any、Unit、Nothing 深度探秘
前端
Web极客码9 小时前
深入了解WordPress网站访客意图
服务器·前端·wordpress
幺风9 小时前
Claude Code 源码分析 — Tool/MCP/Skill 可扩展工具系统
前端·javascript·ai编程
vjmap10 小时前
唯杰地图CAD图层加高性能特效扩展包发布
前端·gis
ZC跨境爬虫10 小时前
3D 地球卫星轨道可视化平台开发 Day7(AI异步加速+卫星系列精简+AI Agent自动评论)
前端·人工智能·3d·html·json
ID_1800790547310 小时前
淘宝 API 上货 / 商品搬家 业务场景实现 + JSON 返回示例
前端·javascript·json
M ? A10 小时前
Vue 动态组件在 React 中,VuReact 会如何实现?
前端·javascript·vue.js·经验分享·react.js·面试·vureact