如何将 URL 参数转换为 JavaScript 对象?
我有一个像这样的字符串:
abc=foo&def=%5Basf%5D&xyz=5
如何将它转换为这样的 JavaScript 对象?
{
abc: 'foo',
def: '[asf]',
xyz: 5
}
I have a string like this:
abc=foo&def=%5Basf%5D&xyz=5
How can I convert it into a JavaScript object like this?
{
abc: 'foo',
def: '[asf]',
xyz: 5
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(30)
到了 2021 年……请认为这个已经过时了。
编辑
此编辑根据评论改进并解释了答案。
示例
分五步解析
abc=foo&def=%5Basf%5D&xyz=5
:abc=foo","def=[asf]","xyz=5
abc":"foo","def":"[asf]","xyz":"5
{"abc":"foo","def ":"[asf]","xyz":"5"}
这是合法的 JSON。
改进的解决方案允许在搜索字符串中使用更多字符。它使用 reviver 函数进行 URI 解码:
示例
给出了
原始答案
一句话:
In the year 2021... Please consider this obsolete.
Edit
This edit improves and explains the answer based on the comments.
Example
Parse
abc=foo&def=%5Basf%5D&xyz=5
in five steps:abc=foo","def=[asf]","xyz=5
abc":"foo","def":"[asf]","xyz":"5
{"abc":"foo","def":"[asf]","xyz":"5"}
which is legal JSON.
An improved solution allows for more characters in the search string. It uses a reviver function for URI decoding:
Example
gives
Original answer
A one-liner:
一个班轮。干净简单。
对于您的具体情况,它将是:
One liner. Clean and simple.
For your specific case, it would be:
2023 ES6/7/8 及后续方法
从 ES6 及后续版本开始,Javascript 提供了多种构造来为此问题创建高性能解决方案。
这包括使用 URLSearchParams 和 迭代器
如果您的用例需要您实际转换它要对象,可以实现以下功能:
基本演示
使用 Object.fromEntries 并传播
我们可以使用 Object.fromEntries,将
paramsToObject
替换为Object.fromEntries(entries)
。从
URLParams
开始,返回一个 iterable 对象,使用 扩展运算符而不是调用.entries
也将根据其规范生成条目:注意:所有值都会根据< a href="https://url.spec.whatwg.org/#interface-urlsearchparams" rel="noreferrer">URLSearchParams 规范
多个相同的键
作为 @siipe指出,包含多个相同键值的字符串将被强制转换为最后一个可用值:
foo=first_value& foo=second_value
本质上会变成:{foo: "second_value"}
。根据这个答案: https://stackoverflow.com/a/1746566/1194694 没有决定要做什么的规范有了它,每个框架的行为都会有所不同。
一个常见的用例是将两个相同的值连接到一个数组中,使输出对象成为:
这可以通过以下代码来实现:
2023 ES6/7/8 and on approach
Starting ES6 and on, Javascript offers several constructs in order to create a performant solution for this issue.
This includes using URLSearchParams and iterators
Should your use case requires you to actually convert it to object, you can implement the following function:
Basic Demo
Using Object.fromEntries and spread
We can use Object.fromEntries, replacing
paramsToObject
withObject.fromEntries(entries)
.Since
URLParams
, returns an iterable object, using the spread operator instead of calling.entries
will also yield entries per its spec:Note: All values are automatically strings as per the URLSearchParams spec
Multiple same keys
As @siipe pointed out, strings containing multiple same-key values will be coerced into the last available value:
foo=first_value&foo=second_value
will in essence become:{foo: "second_value"}
.As per this answer: https://stackoverflow.com/a/1746566/1194694 there's no spec for deciding what to do with it and each framework can behave differently.
A common use case will be to join the two same values into an array, making the output object into:
This can be achieved with the following code:
2024 单行方法
对于您想要将查询参数解析为对象的一般情况:
对于您的特定情况:
用于解析重复(数组)查询参数的 TypeScript 解决方案:
2024 One-Liner Approach
For the general case where you want to parse query params to an object:
For your specific case:
TypeScript solution for parsing repeated (array) query params:
在
&
上拆分以获取名称/值对,然后在=
上拆分每一对。这是一个示例:另一种方法,使用正则表达式:
这改编自 John Resig 的 “搜索但不替换” 。
Split on
&
to get name/value pairs, then split each pair on=
. Here's an example:Another approach, using regular expressions:
This is adapted from John Resig's "Search and Don’t Replace".
到目前为止我发现的建议解决方案并未涵盖更复杂的场景。
我需要转换一个查询字符串,例如
https://random.url.com?Target=Offer&Method=findAll&filters%5Bhas_goals_enabled%5D%5BTRUE%5D=1&filters%5Bstatus%5D=active&fields%5B%5D=id&fields %5B%5D=name&fields%5B%5D=default_goal_name
到对象如:
或:
https://random.url.com?Target=Report&Method=getStats&fields%5B%5D=Offer.name&fields%5B%5D=Advertiser.company&f ields%5B%5D=Stat.clicks&fields%5B%5D=Stat.conversions&fields%5B%5D=Stat.cpa&fields%5B%5D=Stat.payout&fields%5B%5D=Sta t.date&fields%5B%5D=Stat.offer_id&fields%5B%5D=Affiliate.company&groups%5B%5D=Stat.offer_id&groups%5B%5D=Stat.date&a mp;filters%5BStat.affiliate_id%5D%5Bconditional%5D=EQUAL_TO&filters%5BStat.affiliate_id%5D%5Bvalues%5D=1831&limit=9999
INTO:
我将多种解决方案编译并改编成一种实际有效的解决方案:
代码:
The proposed solutions I found so far do not cover more complex scenarios.
I needed to convert a query string like
https://random.url.com?Target=Offer&Method=findAll&filters%5Bhas_goals_enabled%5D%5BTRUE%5D=1&filters%5Bstatus%5D=active&fields%5B%5D=id&fields%5B%5D=name&fields%5B%5D=default_goal_name
into an object like:
OR:
https://random.url.com?Target=Report&Method=getStats&fields%5B%5D=Offer.name&fields%5B%5D=Advertiser.company&fields%5B%5D=Stat.clicks&fields%5B%5D=Stat.conversions&fields%5B%5D=Stat.cpa&fields%5B%5D=Stat.payout&fields%5B%5D=Stat.date&fields%5B%5D=Stat.offer_id&fields%5B%5D=Affiliate.company&groups%5B%5D=Stat.offer_id&groups%5B%5D=Stat.date&filters%5BStat.affiliate_id%5D%5Bconditional%5D=EQUAL_TO&filters%5BStat.affiliate_id%5D%5Bvalues%5D=1831&limit=9999
INTO:
I compiled and adapted multiple solutions into one that actually works:
CODE:
一个简洁的解决方案:
A concise solution:
这是简单的版本,显然您需要添加一些错误检查:
This is the simple version, obviously you'll want to add some error checking:
对于 Node JS,您可以使用 Node JS API
querystring
:文档:https:// /nodejs.org/api/querystring.html
For Node JS, you can use the Node JS API
querystring
:Documentation: https://nodejs.org/api/querystring.html
我发现 $.String.deparam 最完整的预构建解决方案(可以执行嵌套对象等)。查看文档。
I found $.String.deparam the most complete pre built solution (can do nested objects etc.). Check out the documentation.
另一个基于 URLSearchParams 最新标准的解决方案(https://developer.mozilla .org/en-US/docs/Web/API/URLSearchParams)
请注意,此解决方案使用
Array.from (https://developer.mozilla.org/en-US /docs/Web/JavaScript/Reference/Global_Objects/Array/from)
和 _.fromPairs (https://lodash.com/docs#fromPairs)。
由于您可以访问 searchParams.entries() 迭代器,因此创建更兼容的解决方案应该很容易。
Another solution based on the latest standard of URLSearchParams (https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams)
Please note that this solution is making use of
Array.from (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/from)
and _.fromPairs (https://lodash.com/docs#fromPairs) of lodash for the sake of simplicity.
It should be easy to create a more compatible solution since you have access to searchParams.entries() iterator.
ES6 有一个非常简单且不正确的答案:
但这一行代码不涵盖多个相同的键,你必须使用更复杂的东西:
代码将生成以下结构:
There is quite simple and incorrect answer with ES6:
But this one line code do not cover multiple same keys, you have to use something more complicated:
Code will generate follow structure:
我遇到了同样的问题,尝试了这里的解决方案,但没有一个真正起作用,因为我在 URL 参数中有数组,如下所示:
所以我最终编写了自己的 JS 函数,它从 URI 中的参数生成一个数组:
I had the same problem, tried the solutions here, but none of them really worked, since I had arrays in the URL parameters, like this:
So I ended up writing my own JS function, which makes an array out of the param in URI:
ES6 one liner(如果我们可以这样称呼它)
[...new URLSearchParams(location.search).entries()].reduce((prev, [key,val]) =>; {上一个[键] = val; 返回上一个}, {})
ES6 one liner (if we can call it that way seeing the long line)
[...new URLSearchParams(location.search).entries()].reduce((prev, [key,val]) => {prev[key] = val; return prev}, {})
最简单的方法之一是使用 URLSearchParam 接口。
下面是工作代码片段:
One of the simplest way to do this using URLSearchParam interface.
Below is the working code snippet:
使用
URLSearchParams
JavaScript Web API 非常简单,##有用的链接
|谷歌开发者
Pretty easy using the
URLSearchParams
JavaScript Web API,##Useful Links
| Google Developers
使用 ES6、URL API 和 URLSearchParams API。
Using ES6, URL API and URLSearchParams API.
一个简单的答案是内置原生 Node 模块。(无第三方 npm 模块)
querystring 模块提供了用于解析和格式化 URL 查询字符串的实用程序。可以使用以下方式访问它:
One simple answer with build in native Node module.(No third party npm modules)
The querystring module provides utilities for parsing and formatting URL query strings. It can be accessed using:
据我所知,没有本地解决方案。如果您偶然使用该框架,Dojo 有一个内置的反序列化方法。
否则,您可以自己简单地实现它:
编辑:添加decodeURIComponent()
There is no native solution that I'm aware of. Dojo has a built-in unserialization method if you use that framework by chance.
Otherwise you can implement it yourself rather simply:
edit: added decodeURIComponent()
有一个名为 YouAreI.js 的轻量级库,它经过测试并且使这变得非常简单。
There's a lightweight library called YouAreI.js that's tested and makes this really easy.
如果您使用 URI.js,则可以使用:
https:// medialize.github.io/URI.js/docs.html#static-parseQuery
If you are using URI.js, you can use:
https://medialize.github.io/URI.js/docs.html#static-parseQuery
这似乎是最好的解决方案,因为它考虑了多个同名参数。
我后来决定也将它转换为 jQuery 插件...
现在,第一个插件仅接受参数,但 jQuery 插件将获取整个 url 并返回序列化参数。
This seems to be the best solution as it takes multiple parameters of the same name into consideration.
I later decided to convert it to a jQuery plugin too...
Now, the first will accept the parameters only but the jQuery plugin will take the whole url and return the serialized parameters.
这是我使用的一个:
基本用法,例如。
?a=aa&b=bb
对象 {a: "aa", b: "bb"}
重复参数,例如
?a=aa&b=bb&c=cc&c=马铃薯
对象 {a: "aa", b: "bb", c: ["cc","potato"]}
缺少键,例如。
?a=aa&b=bb&=cc
对象 {a: "aa", b: "bb"}
缺少值,例如。
?a=aa&b=bb&c
Object {a: "aa", b: "bb"}
上述 JSON/regex 解决方案在这个古怪的网址上抛出语法错误:
?a=aa&b=bb&c=&=dd&e
对象 {a: "aa", b: "bb", c: ""}
Here's one I use:
Basic usage, eg.
?a=aa&b=bb
Object {a: "aa", b: "bb"}
Duplicate params, eg.
?a=aa&b=bb&c=cc&c=potato
Object {a: "aa", b: "bb", c: ["cc","potato"]}
Missing keys, eg.
?a=aa&b=bb&=cc
Object {a: "aa", b: "bb"}
Missing values, eg.
?a=aa&b=bb&c
Object {a: "aa", b: "bb"}
The above JSON/regex solutions throw a syntax error on this wacky url:
?a=aa&b=bb&c=&=dd&e
Object {a: "aa", b: "bb", c: ""}
这是我的快速但肮脏的版本,基本上它拆分了用“&”分隔的 URL 参数到数组元素中,然后迭代该数组,将由“=”分隔的键/值对添加到对象中。我使用decodeURIComponent()将编码字符转换为其正常的字符串等效项(因此%20变成空格,%26变成“&”等):
示例:
返回
唯一的问题是xyz是一个字符串而不是一个数字(由于使用了decodeURIComponent()),但除此之外,它是一个不错的起点。
Here's my quick and dirty version, basically its splitting up the URL parameters separated by '&' into array elements, and then iterates over that array adding key/value pairs separated by '=' into an object. I'm using decodeURIComponent() to translate the encoded characters to their normal string equivalents (so %20 becomes a space, %26 becomes '&', etc):
example:
returns
The only issue is that xyz is a string and not a number (due to using decodeURIComponent()), but beyond that its not a bad starting point.
如果您需要递归,可以使用小型 js-extension-ling 库。
这将输出如下内容:
注意:它基于 locutus parse_str 函数 (https://locutus.io /php/strings/parse_str/)。
If you need recursion, you can use the tiny js-extension-ling library.
This will output something like this:
Note: it's based on locutus parse_str function (https://locutus.io/php/strings/parse_str/).
首先你需要定义什么是 GET VAR:
而不是仅仅阅读:
并使用类似:
FIRST U NEED TO DEFINE WHAT'S A GET VAR:
Than just read:
and use like:
我还需要在 URL 的查询部分处理
+
(decodeURIComponent 不't),所以我将 Wolfgang 的代码改编为:在我的例子中,我使用 jQuery 来获取 URL 就绪的表单参数,然后用这个技巧构建一个对象,然后我可以轻松更新参数在对象上并重建查询 URL,例如:
I needed to also deal with
+
in the query part of the URL (decodeURIComponent doesn't), so I adapted Wolfgang's code to become:In my case, I'm using jQuery to get URL-ready form parameters, then this trick to build an object out of it and I can then easily update parameters on the object and rebuild the query URL, e.g.: