是否有一个快速和简单的方法来编码JavaScript对象到字符串,我可以通过GET请求传递?

没有jQuery,没有其他框架-只有纯JavaScript:)


当前回答

只使用URLSearchParams,这适用于当前所有浏览器

new URLSearchParams(object).toString()

其他回答

以更好的方式做这件事。

它可以处理标准查询形式的递归对象或数组,如a=val&b[0]=val&b[1]=val&c=val&d[some key]=val。这是最后一个函数。

逻辑、功能

const objectToQueryString = (initialObj) => {
  const reducer = (obj, parentPrefix = null) => (prev, key) => {
    const val = obj[key];
    key = encodeURIComponent(key);
    const prefix = parentPrefix ? `${parentPrefix}[${key}]` : key;

    if (val == null || typeof val === 'function') {
      prev.push(`${prefix}=`);
      return prev;
    }

    if (['number', 'boolean', 'string'].includes(typeof val)) {
      prev.push(`${prefix}=${encodeURIComponent(val)}`);
      return prev;
    }

    prev.push(Object.keys(val).reduce(reducer(val, prefix), []).join('&'));
    return prev;
  };

  return Object.keys(initialObj).reduce(reducer(initialObj), []).join('&');
};

例子

const testCase1 = {
  name: 'Full Name',
  age: 30
}

const testCase2 = {
  name: 'Full Name',
  age: 30,
  children: [
    {name: 'Child foo'},
    {name: 'Foo again'}
  ],
  wife: {
    name: 'Very Difficult to say here'
  }
}

console.log(objectToQueryString(testCase1));
console.log(objectToQueryString(testCase2));

现场测试

展开下面的代码片段,在浏览器中验证结果-

const objectToQueryString = (initialObj) => { const reducer = (obj, parentPrefix = null) => (prev, key) => { const val = obj[key]; key = encodeURIComponent(key); const prefix = parentPrefix ? `${parentPrefix}[${key}]` : key; if (val == null || typeof val === 'function') { prev.push(`${prefix}=`); return prev; } if (['number', 'boolean', 'string'].includes(typeof val)) { prev.push(`${prefix}=${encodeURIComponent(val)}`); return prev; } prev.push(Object.keys(val).reduce(reducer(val, prefix), []).join('&')); return prev; }; return Object.keys(initialObj).reduce(reducer(initialObj), []).join('&'); }; const testCase1 = { name: 'Full Name', age: 30 } const testCase2 = { name: 'Full Name', age: 30, children: [ {name: 'Child foo'}, {name: 'Foo again'} ], wife: { name: 'Very Difficult to say here' } } console.log(objectToQueryString(testCase1)); console.log(objectToQueryString(testCase2));

需要考虑的事情。

它跳过函数、null和未定义的值 它跳过空对象和数组的键和值。 它不处理用new Number(1)或new String('my String ')创建的Number或String对象,因为没有人应该这样做

对用户187291接受的解决方案的一个小修改:

serialize = function(obj) {
   var str = [];
   for(var p in obj){
       if (obj.hasOwnProperty(p)) {
           str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p]));
       }
   }
   return str.join("&");
}

检查对象上的hasOwnProperty使JSLint和JSHint高兴,它防止意外序列化对象的方法或其他东西,如果对象不是一个简单的字典。有关JavaScript编程语言的代码约定的语句,请参阅上一段。

好吧,这是一个旧的帖子,但我正面临这个问题,我已经找到了我的个人解决方案。也许可以帮助别人…

     function objToQueryString(obj){
        var k = Object.keys(obj);
        var s = "";
        for(var i=0;i<k.length;i++) {
            s += k[i] + "=" + encodeURIComponent(obj[k[i]]);
            if (i != k.length -1) s += "&";
        }
        return s;
     };

如果有很多嵌套对象,前面的答案就不起作用了。

相反,你可以从jquery-param/jquery-param.js中选择函数参数。这对我来说非常有效!

    var param = function (a) {
    var s = [], rbracket = /\[\]$/,
        isArray = function (obj) {
            return Object.prototype.toString.call(obj) === '[object Array]';
        }, add = function (k, v) {
            v = typeof v === 'function' ? v() : v === null ? '' : v === undefined ? '' : v;
            s[s.length] = encodeURIComponent(k) + '=' + encodeURIComponent(v);
        }, buildParams = function (prefix, obj) {
            var i, len, key;

            if (prefix) {
                if (isArray(obj)) {
                    for (i = 0, len = obj.length; i < len; i++) {
                        if (rbracket.test(prefix)) {
                            add(prefix, obj[i]);
                        } else {
                            buildParams(prefix + '[' + (typeof obj[i] === 'object' ? i : '') + ']', obj[i]);
                        }
                    }
                } else if (obj && String(obj) === '[object Object]') {
                    for (key in obj) {
                        buildParams(prefix + '[' + key + ']', obj[key]);
                    }
                } else {
                    add(prefix, obj);
                }
            } else if (isArray(obj)) {
                for (i = 0, len = obj.length; i < len; i++) {
                    add(obj[i].name, obj[i].value);
                }
            } else {
                for (key in obj) {
                    buildParams(key, obj[key]);
                }
            }
            return s;
        };

    return buildParams('', a).join('&').replace(/%20/g, '+');
};

如果你想将整个对象作为一个参数传递,例如,?filter={param1: "val1", param2: "val2"}:

const serializeObject = (obj) => {
  let objStr = JSON.stringify(obj);

  objStr = objStr.replace(/\{/g, encodeURIComponent("{"));
  objStr = objStr.replace(/}/g, encodeURIComponent("}"));
  objStr = objStr.replace(/:/g, encodeURIComponent(":"));

  return objStr;
};

let res = serializeObject({param1: "val1", param2: "val2"});
console.log("serializeObject:", res); //%7B"param1"%3A"val1","param2"%3A"val2"%7D
console.log("serializeObject-decoded:", decodeURIComponent(res)); //{"param1":"val1","param2":"val2"}