从 URLSearchParams 恢复数组时,Object.fromEntries 无法按预期工作?



简单代码:

const o = { arr: ['a', 'b'] }
const s = new URLSearchParams(o).toString();
// restore:
const r = Object.fromEntries(new URLSearchParams(s));
console.log({ r })

输出:

r: { arr: "a,b" } // expected: r: { arr: ["a", "b"] }

如何使 Object.fromEntries 返回预期的数组?

URLSearchParams 将值强制为字符串。这里的值[ 'a', 'b' ]是一个数组,所以调用数组的toString方法,就像arr.join(',')一样,产生字符串"a,b"

new URLSearchParams({ arr: ['a', 'b'] }).get('arr'); // "a,b"

当您初始化 USP 对象时会发生这种情况——它与Object.fromEntries无关。这两个 API 都无法自动往返此序列化值,因为它不知道您希望逗号分隔的字符串成为字符串数组。不过,您可以为这些值编写自定义反序列化逻辑。


搜索参数中的类似数组或类似集合的值通常表示为同一键的多次出现。要像这样初始化USP实例,您需要传入条目而不是类似记录的对象。例如:

const usp = new URLSearchParams([ [ 'arr', 'a' ], [ 'arr', 'b' ] ]);
usp.getAll('arr'); // [ 'a', 'b' ]
usp.toString();    // arr=a&arr=b

这种"复数"值的方法有一些优点(USP API非常适合它,它不涉及任何自定义DSL放在真正的URL语法和语义之上(和缺点(解释需要特定的知识 - 参数的预期"类型"没有在源中传达,因为你不能一般区分

一个参数,一个代表一个成员的数组和一个意味着单一值的数组(。但是,如果您确实以这种方式处理数组,则不能直接使用Object.fromEntries(usp)将其转换为通用对象 - 它最终将始终arr设置为出现的最后一个值。但是,您可以在两者之间执行一些映射逻辑,以处理要解释为数组的键。

最新更新