Next.js传递含数组对象为查询参数及Object.entries正确用法
问题描述
需要将内部包含数组的嵌套对象作为请求查询参数传递,初始实现代码如下:
const fa = { 'variants.attributes.Clothing_color': { terms: ['Navy Blue', 'Golden Croissant'], }, }; const serialize = function (obj) { var str = []; for (var p in obj) if (obj.hasOwnProperty(p)) { str.push(encodeURIComponent(p) + '=' + encodeURIComponent(obj[p])); } return str.join('&'); }; const urlP = serialize(fa); router.push({ pathname: router.asPath.split('?')[0] as string, query: { facets: urlP }, });
按照上述实现,URL中的查询参数显示为 ?facets=variants.attributes.Clothing_color%3D%255Bobject%2520Object%255D,后端使用Object.entries(facets)处理该参数时,得到的是字符串逐个拆分组成的数组,而非预期的对象结构。
待解决的两个疑问:
- Next.js中将对象作为查询参数传递的正确方式是什么?
- 执行
Object.entries()操作的正确方式是什么?
问题根因
结果不符合预期由两个核心错误导致:
- 自定义
serialize方法存在逻辑缺陷:遍历对象属性时,直接对嵌套对象类型的属性值调用encodeURIComponent,JS会自动将对象隐式转换为字符串[object Object],这就是URL中出现乱码片段的根本原因。 - 后端缺少反序列化步骤:URL查询参数本质是扁平字符串键值对,无法直接承载复杂嵌套对象,拿到参数后直接对字符串调用
Object.entries,会把字符串按字符索引拆成键值对数组,自然得不到预期的对象条目。
解决方案
1. Next.js 传递复杂对象查询参数的正确方式
不需要手写复杂的序列化逻辑,直接用JSON.stringify把复杂对象转为JSON字符串后作为参数值传递即可,Next.js会自动处理URL编码,不需要手动调用encodeURIComponent:
const fa = { 'variants.attributes.Clothing_color': { terms: ['Navy Blue', 'Golden Croissant'], }, }; router.push({ pathname: router.asPath.split('?')[0], query: { facets: JSON.stringify(fa) }, });
如果筛选条件体量极大、超出URL长度限制,不建议将全部参数放在查询串中,可改用POST请求传递,或配合客户端状态存储筛选条件。
2. 后端参数处理与Object.entries的正确用法
拿到facets参数后,先做异常捕获下的反序列化,将JSON字符串还原为原始JS对象,再调用Object.entries遍历即可:
// 服务端处理逻辑示例(以getServerSideProps为例) export async function getServerSideProps(context) { const { facets } = context.query; let facetObj = {}; try { // 反序列化还原原始对象结构 facetObj = facets ? JSON.parse(facets) : {}; } catch (e) { // 兜底处理参数格式非法的场景 console.error('facets参数格式不合法', e); } // 此时facetObj为完整对象结构,可正常调用Object.entries const facetEntries = Object.entries(facetObj); // 执行业务逻辑 return { props: { facetEntries } } }
提示:如果使用新版Next.js App Router,在服务端组件/route handler中从
searchParams拿到参数后,处理逻辑和上述一致,先反序列化再操作即可。
内容的提问来源于stack exchange,提问作者ViP
相关产品推荐
相关产品推荐

