如何将URL参数转换为JavaScript对象?

454

我有一个像这样的字符串:

abc=foo&def=%5Basf%5D&xyz=5

我怎么能将它转换为这样的JavaScript对象?

{
  abc: 'foo',
  def: '[asf]',
  xyz: 5
}

请参见https://dev59.com/nHNA5IYBdhLWcg3wmfAa。 - Bergi
1
这并不是:https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams/get#Example https://developer.mozilla.org/en-US/docs/Web/API/URL/searchParams#Example (尽管我们还需要等待一段时间,让所有浏览器都能够支持它) - Arthur
Object.fromEntries(Array.from(new URLSearchParams('abc=foo&def=%5Basf%5D&xyz=5'))) - undefined
34个回答

9

另一种基于最新的URLSearchParams标准的解决方案(https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams)

function getQueryParamsObject() {
  const searchParams = new URLSearchParams(location.search.slice(1));
  return searchParams
    ? _.fromPairs(Array.from(searchParams.entries()))
    : {};
}

请注意,此解决方案利用了 Array.from _.fromPairs(lodash的函数)以简化操作。
由于您可以访问searchParams.entries()迭代器,因此应该很容易创建更兼容的解决方案。

7

我也遇到了同样的问题,尝试了这里的解决方案,但是它们都没有真正起作用,因为我的URL参数中包含了数组,像这样:

?param[]=5&param[]=8&othr_param=abc&param[]=string

所以我最终编写了自己的JS函数,该函数将URI中的参数转换为数组:
/**
 * Creates an object from URL encoded data
 */
var createObjFromURI = function() {
    var uri = decodeURI(location.search.substr(1));
    var chunks = uri.split('&');
    var params = Object();

    for (var i=0; i < chunks.length ; i++) {
        var chunk = chunks[i].split('=');
        if(chunk[0].search("\\[\\]") !== -1) {
            if( typeof params[chunk[0]] === 'undefined' ) {
                params[chunk[0]] = [chunk[1]];

            } else {
                params[chunk[0]].push(chunk[1]);
            }


        } else {
            params[chunk[0]] = chunk[1];
        }
    }

    return params;
}

3
这非常有帮助,几乎完全符合我的要求。但是,如果URL参数是像“bacon [] = eggs&bacon [] = toast”这样的格式,我不喜欢对象中保留“[]”。因此,在“if(chunk[0].search("\[\]") !== -1) {”之后,我添加了一行代码,“chunk [0] = chunk [0] .replace (/ \ [] $ /,'');”。 - rgbflawed
@rgbflawed,为了未来读者和可读性,您应该编辑答案。 - Webwoman
使用 const 代替 var,因为有人可能会执行 createObjFromURI = 'some text',这样会破坏代码。如果使用 const,那么运行 createObjFromURI = 'some text' 的人将会出现错误,无法将值分配给常量变量。 - Justin Liu

6

使用JavaScript Web API URLSearchParams 很容易实现,

var paramsString = "abc=foo&def=%5Basf%5D&xyz=5";

//returns an iterator object
var searchParams = new URLSearchParams(paramsString);

//Usage
for (let p of searchParams) {
  console.log(p);
}

//Get the query strings
console.log(searchParams.toString());

//You can also pass in objects

var paramsObject = {abc:"forum",def:"%5Basf%5D",xyz:"5"}

//returns an iterator object
var searchParams = new URLSearchParams(paramsObject);

//Usage
for (let p of searchParams) {
  console.log(p);
}

//Get the query strings
console.log(searchParams.toString());

##有用的链接

注意: 不支持 IE 浏览器


6

使用URLSearchParams接口是最简单的方式之一。

以下是工作代码片段:

let paramObj={},
    querystring=window.location.search,
    searchParams = new URLSearchParams(querystring);    

  //*** :loop to add key and values to the param object.
 searchParams.forEach(function(value, key) {
      paramObj[key] = value;
   });

6

使用 ES6 有一个相当简单但不正确的答案:

console.log(
  Object.fromEntries(new URLSearchParams(`abc=foo&def=%5Basf%5D&xyz=5`))
);

但是这一行代码不能处理多个相同的键,你需要使用更复杂的方法:

function parseParams(params) {
  const output = [];
  const searchParams = new URLSearchParams(params);

  // Set will return only unique keys()
  new Set([...searchParams.keys()])
    .forEach(key => {
      output[key] = searchParams.getAll(key).length > 1 ?  
        searchParams.getAll(key) : // get multiple values
        searchParams.get(key); // get single value
    });

  return output;
}

console.log(
   parseParams('abc=foo&cars=Ford&cars=BMW&cars=Skoda&cars=Mercedes')
)

代码将生成以下结构:

[
  abc: "foo"
  cars: ["Ford", "BMW", "Skoda", "Mercedes"]
]

5

ES6一行代码(尽管由于代码行长,我们可能不太想这样称呼它)

[...new URLSearchParams(location.search).entries()].reduce((prev, [key,val]) => {prev[key] = val; return prev}, {})

将URL参数解析成对象字面量的一行代码。


2
你也可以解构 cur 来增加一些清晰度。.reduce((prev, [key, val]) => {prev[key] = val}) - Allan Lei
我喜欢你的建议,Allan Lei。我会更新我的答案。 - fadomire

5
使用ES6,URL API和URLSearchParams API。
function objectifyQueryString(url) {
  let _url = new URL(url);
  let _params = new URLSearchParams(_url.search);
  let query = Array.from(_params.keys()).reduce((sum, value)=>{
    return Object.assign({[value]: _params.get(value)}, sum);
  }, {});
  return query;
}

5

使用内置的 Node 模块可以给出一个简单的答案。(无需第三方 npm 模块)

querystring 模块提供了解析和格式化 URL 查询字符串的实用工具。可以通过以下方式访问它:

const querystring = require('querystring');

const body = "abc=foo&def=%5Basf%5D&xyz=5"
const parseJSON = querystring.parse(body);
console.log(parseJSON);

不错。我已经尝试过这个方法,它在Angular中可以正常工作,我正在使用import * as querystring from "querystring"; - Snowbases
这个功能也可以在浏览器中使用,只需安装相同名称和功能的任何npm包(npm install querystring)。 - rattray

3

/**
 * Parses and builds Object of URL query string.
 * @param {string} query The URL query string.
 * @return {!Object<string, string>}
 */
function parseQueryString(query) {
  if (!query) {
    return {};
  }
  return (/^[?#]/.test(query) ? query.slice(1) : query)
      .split('&')
      .reduce((params, param) => {
        const item = param.split('=');
        const key = decodeURIComponent(item[0] || '');
        const value = decodeURIComponent(item[1] || '');
        if (key) {
          params[key] = value;
        }
        return params;
      }, {});
}

console.log(parseQueryString('?v=MFa9pvnVe0w&ku=user&from=89&aw=1'))
see log


3
我目前了解不到任何本地化方案。如果你恰好使用Dojo框架,它具有内置的反序列化方法。
否则,你可以自己简单地实现它:
function unserialize(str) {
  str = decodeURIComponent(str);
  var chunks = str.split('&'),
      obj = {};
  for(var c=0; c < chunks.length; c++) {
    var split = chunks[c].split('=', 2);
    obj[split[0]] = split[1];
  }
  return obj;
}

编辑:添加了decodeURIComponent()


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接