我有一个这样的字符串:

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

如何将其转换为这样的JavaScript对象?

{
  abc: 'foo',
  def: '[asf]',
  xyz: 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);

其他回答

在Mike Causer回答的基础上,我创建了这个函数,它考虑了具有相同键的多个参数(foo=bar&foo=baz)和逗号分隔的参数(foo=bar,baz,bin)。它还允许您搜索某个查询键。

function getQueryParams(queryKey) {
    var queryString = window.location.search;
    var query = {};
    var pairs = (queryString[0] === '?' ? queryString.substr(1) : queryString).split('&');
    for (var i = 0; i < pairs.length; i++) {
        var pair = pairs[i].split('=');
        var key = decodeURIComponent(pair[0]);
        var value = decodeURIComponent(pair[1] || '');
        // Se possui uma vírgula no valor, converter em um array
        value = (value.indexOf(',') === -1 ? value : value.split(','));

        // Se a key já existe, tratar ela como um array
        if (query[key]) {
            if (query[key].constructor === Array) {
                // Array.concat() faz merge se o valor inserido for um array
                query[key] = query[key].concat(value);
            } else {
                // Se não for um array, criar um array contendo o valor anterior e o novo valor
                query[key] = [query[key], value];
            }
        } else {
            query[key] = value;
        }
    }

    if (typeof queryKey === 'undefined') {
        return query;
    } else {
        return query[queryKey];
    }
}

示例输入: foo.html吗?博兹,foo = bar&foo = baz&foo =鹿角的第二叉,buz&bar = 1, 2, 3

示例输出

{
    foo: ["bar","baz","bez","boz","buz"],
    bar: ["1","2","3"]
}

下面是硅制品方法的一个更简化的版本。

下面的函数可以从USVString或Location解析查询字符串。

/** * Returns a plain object representation of a URLSearchParams object. * @param {USVString} search - A URL querystring * @return {Object} a key-value pair object from a URL querystring */ const parseSearch = (search) => [...new URLSearchParams(search).entries()] .reduce((acc, [key, val]) => ({ ...acc, // eslint-disable-next-line no-nested-ternary [key]: Object.prototype.hasOwnProperty.call(acc, key) ? Array.isArray(acc[key]) ? [...acc[key], val] : [acc[key], val] : val }), {}); /** * Returns a plain object representation of a URLSearchParams object. * @param {Location} location - Either a document or window location, or React useLocation() * @return {Object} a key-value pair object from a URL querystring */ const parseLocationSearch = (location) => parseSearch(location.search); console.log(parseSearch('?foo=bar&x=y&ids=%5B1%2C2%2C3%5D&ids=%5B4%2C5%2C6%5D')); .as-console-wrapper { top: 0; max-height: 100% !important; }

下面是上面代码的一行代码(125字节):

f是parsearchch

f=s=>[...new URLSearchParams(s).entries()].reduce((a,[k,v])=>({...a,[k]:a[k]?Array.isArray(a[k])?[...a[k],v]:[a[k],v]:v}),{})

Edit

下面是一个序列化和更新的方法:

const parseSearch = (search) => [...new URLSearchParams(search).entries()] .reduce((acc, [key, val]) => ({ ...acc, // eslint-disable-next-line no-nested-ternary [key]: Object.prototype.hasOwnProperty.call(acc, key) ? Array.isArray(acc[key]) ? [...acc[key], val] : [acc[key], val] : val }), {}); const toQueryString = (params) => `?${Object.entries(params) .flatMap(([key, values]) => Array.isArray(values) ? values.map(value => [key, value]) : [[key, values]]) .map(pair => pair.map(val => encodeURIComponent(val)).join('=')) .join('&')}`; const updateQueryString = (search, update) => (parsed => toQueryString(update instanceof Function ? update(parsed) : { ...parsed, ...update })) (parseSearch(search)); const queryString = '?foo=bar&x=y&ids=%5B1%2C2%2C3%5D&ids=%5B4%2C5%2C6%5D'; const parsedQuery = parseSearch(queryString); console.log(parsedQuery); console.log(toQueryString(parsedQuery) === queryString); const updatedQuerySimple = updateQueryString(queryString, { foo: 'baz', x: 'z', }); console.log(updatedQuerySimple); console.log(parseSearch(updatedQuerySimple)); const updatedQuery = updateQueryString(updatedQuerySimple, parsed => ({ ...parsed, ids: [ ...parsed.ids, JSON.stringify([7,8,9]) ] })); console.log(updatedQuery); console.log(parseSearch(updatedQuery)); .as-console-wrapper { top: 0; max-height: 100% !important; }

在&上拆分以获得名称/值对,然后在=上拆分每对。这里有一个例子:

var str = "abc=foo&def=%5Basf%5D&xy%5Bz=5"
var obj = str.split("&").reduce(function(prev, curr, i, arr) {
    var p = curr.split("=");
    prev[decodeURIComponent(p[0])] = decodeURIComponent(p[1]);
    return prev;
}, {});

另一种方法,使用正则表达式:

var obj = {}; 
str.replace(/([^=&]+)=([^&]*)/g, function(m, key, value) {
    obj[decodeURIComponent(key)] = decodeURIComponent(value);
}); 

本文改编自约翰·瑞西格的《搜索和不替换》。

使用URLSearchParams JavaScript Web API非常简单,

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());

# #的有用链接

URLSearchParams - Web api | MDN 简单的URL操作与URLSearchParams | Web |谷歌开发者

注意:IE不支持

许多其他的解决方案没有考虑到边界情况。

这个可以处理

空键a=1&b=2& 空值a=1&b 空值a=1&b= 未编码的等号a=1&b=2=3=4

  decodeQueryString: qs => {
    // expects qs to not have a ?
    // return if empty qs
    if (qs === '') return {};
    return qs.split('&').reduce((acc, pair) => {
      // skip no param at all a=1&b=2&
      if (pair.length === 0) return acc;
      const parts = pair.split('=');
      // fix params without value
      if (parts.length === 1) parts[1] = '';
      // for value handle multiple unencoded = signs
      const key = decodeURIComponent(parts[0]);
      const value = decodeURIComponent(parts.slice(1).join('='));
      acc[key] = value;
      return acc;
    }, {});
  },