Vue/Axios/Node中多层嵌套GET查询参数转字符串问题排查与解决
我之前也碰到过一模一样的问题!这其实是因为前后端默认的查询参数序列化/解析规则不匹配导致的,下面给你拆解原因和不用JSON.parse的解决办法:
问题原因
当你发送多层嵌套(超过2层)的查询参数时,前端默认的序列化工具(比如Vue常用的axios默认依赖的querystring模块)和后端Express默认的参数解析器(同样基于querystring),默认只支持解析2层嵌套的参数。超过这个层级后,querystring会把深层的嵌套对象直接序列化为JSON字符串,而不是继续拆解成键值对格式,所以后端收到的firstQuery就是一个JSON字符串,而非嵌套对象,自然访问firstQuery.insideOne.abc会返回undefined。
不用JSON.parse的解决方案
方案1:前端调整参数序列化规则(推荐)
如果用axios发送请求,可以改用qs库来序列化查询参数,它支持无限层级的嵌套解析。步骤如下:
- 先安装
qs:
npm install qs --save
- 在axios的全局配置里指定
paramsSerializer:
import axios from 'axios'; import qs from 'qs'; axios.defaults.paramsSerializer = params => { return qs.stringify(params, { depth: Infinity }); };
这样发送的嵌套参数会被序列化为后端能正确解析的格式,比如你的示例参数会被转成:firstQuery[insideOne][abc]=cde&secondQuery[insideTwo][cde]=efg
后端就能直接拿到嵌套对象,不需要额外解析。
方案2:后端调整参数解析器的嵌套深度限制
如果你用的是Express框架,可以修改默认的urlencoded中间件配置,把depth参数调大(或者设为Infinity):
const express = require('express'); const app = express(); // 调整解析深度,支持无限层级 app.use(express.urlencoded({ extended: true, depth: Infinity })); // 如果你是手动用querystring解析请求参数,也可以加depth配置: const querystring = require('querystring'); const parsedQuery = querystring.parse(req.url.split('?')[1], undefined, undefined, { depth: Infinity });
这样后端的解析器就能正确处理超过2层的嵌套参数,把它们解析成对象而不是字符串。
总结
两种方案选一种就行,个人更推荐前端用qs序列化,因为这样不管后端是什么框架,都能兼容;如果只调整后端,那前端的序列化格式必须和后端解析规则匹配才行。
内容的提问来源于stack exchange,提问作者isik_hi

