在本文中,我将解释如何将查询字符串转换为对象,反之亦然,这将使您能够轻松获取和设置 URL 查询参数。
尽管这是一项常见的任务,但我发现自己反复在谷歌上搜索它,因为做这件事的方法不止一种。
但在我们开始之前,查询字符串又是什么?
查询字符串是URL 中问号之后的部分。
例如,当你用谷歌搜索某些东西时,你可以在 URL 中看到你的搜索查询作为查询参数:
https://www.google.com/search?q=something
使用 URL 时,解析和创建这些查询是一项常见任务,过去需要手动函数来解析字符串。
然而,如今,这要归功于URLSearchParams接口,这要容易得多,我们将在本教程中主要使用它。
这个 API 的浏览器支持也很好。正如您在此处所见,覆盖了所有用户的 95% 以上。
如何创建查询字符串
发出 API 请求时,我们通常需要将查询参数附加到 URL。
使用URLSearchParamsAPI,我们可以简单地将带有参数的对象传递给类的构造函数:
const params = new URLSearchParams({ foo: "1", bar: "2" });
我们还可以传递带有元组或查询字符串的数组。
完成后,我们现在有一个URLSearchParams类的实例。我们可以通过调用并将其附加到我们的 URL 来获取它的字符串版本toString。
const query = params.toString(); // Output: foo=1&bar=2
const url = `https://thecatapi.com/?${query}`;
使用URL构造函数构建 URL
使用对象构造函数创建 URL 更容易URL。
我们可以将查询设置为一个URLSearchParams对象;fetch也接受此对象而不是字符串。
const url = new URL("https://thecatapi.com/");
// Equals "?breed=aegan&categories=sinks%2Cspace"
url.search = new URLSearchParams({
breed: "aegan",
categories: ["sinks", "space"],
});
const response = await fetch(url);
如何从查询字符串中获取 URL 参数
现在,当我们想将查询字符串转换为对象时,我们可以做什么呢?
假设我们有一个完整的 URL,我们想从中提取查询:
const urlString = "https://thecatapi.com/?breed=aegan&categories=sinks%2Cspace";
我们可以将其转换为 URL 对象并URLSearchParams通过以下方式访问该对象url.searchParams:
const urlString = "https://thecatapi.com/?breed=aegan&categories=sinks%2Cspace";
let url = new URL(urlString);
url.searchParams.get("breed"); // "aegan";
该URLSearchParams接口有一些有用的函数,允许我们从 URL 中提取数据,例如get、getAll、keys或has。您可以在MDN Web Docs上阅读有关这些功能的更多信息。
虽然在大多数情况下这应该足够了,但我们可能还是希望将其转换为常规对象。
将 URLSearchParams 转换为对象
在某些用例中,我们需要在对象而不是接口中包含搜索参数URLSearchParams。
这个很棒的 StackOverflow 答案帮助我实现了这一目标,因此归功于作者。如果对您也有帮助,请给答案点个赞!
function paramsToObject(entries) {
const result = {};
for (const [key, value] of entries) {
// each 'entry' is a [key, value] tupple
result[key] = value;
}
return result;
}
如果我们的查询字符串中只有原始值,这种方法很有效。
但是,当我们想要使用数组搜索查询时,就会出现问题。
在搜索查询中使用数组解析 URL
使用数组解析 URL 是一个更复杂的主题,因为没有在 URL 中定义它们的标准化方法,这意味着 APIURLSearchParams不支持解析数组或对象。
有大量的实现:数组可以通过重复参数来定义......
?foo=bar&foo=qux
...带方括号...
?foo[]=bar&foo[]=qux # URL-encoded: ?foo%5B%5D=bar&foo%5B%5D=qux
...或以逗号分隔。
?foo=bar,qux
如果您好奇的话,这篇文章对此进行了更详细的解释。
除了提到的这些格式之外,还有更多我不能在这里列出的格式,因为每个 API 都可以实现自己的语法。
从中得出的结论是,我们要么将其掌握在自己手中并创建一个根据实现解析搜索字符串的函数,要么我们使用支持大多数情况的库(如 query- string)。
下面是一个这样的函数的例子,它实现了方括号语法(例如?foo[]=a&foo[]=b):
const getQueryParams = (query) => {
let params = {};
new URLSearchParams(query).forEach((value, key) => {
let decodedKey = decodeURIComponent(key);
let decodedValue = decodeURIComponent(value);
// This key is part of an array
if (decodedKey.endsWith("[]")) {
decodedKey = decodedKey.replace("[]", "");
params[decodedKey] || (params[decodedKey] = []);
params[decodedKey].push(decodedValue);
// Just a regular parameter
} else {
params[decodedKey] = decodedValue;
}
});
return params;
};
console.log(getQueryParams("?b[]=1&b[]=2&a=abc&c[]=1"));
灵感来自这个Gist。
{ b: [ '1', '2' ], a: 'abc', c: [ '1' ] }
解析其他实现看起来类似,但是,在处理多种语法时,我强烈建议使用query-string,因为它经过充分测试并支持大多数数组实现。
浏览器支持:

结论
该URLSearchParamsAPI 现在得到了很好的支持,并提供了处理搜索查询时所需的核心功能。
但是,由于对象和数组未标准化,因此它无法提供所有情况下所需的功能。
如果您的应用程序有更高级的用例,您应该考虑使用库或创建自己的函数来正确解析和创建查询字符串。
相关文档:
本机 API 的官方文档URLSearchParams。
用于解析和创建查询字符串的推荐包。
希望本文对您有所帮助。