如何将Object序列化为URL查询参数列表?

bob*_*oap 126 javascript

在不知道JavaScript的键的情况下Object,我怎么能像...

var obj = {
   param1: 'something',
   param2: 'somethingelse',
   param3: 'another'
}

obj[param4] = 'yetanother';
Run Code Online (Sandbox Code Playgroud)

... INTO ...

var str = 'param1=something&param2=somethingelse&param3=another&param4=yetanother';
Run Code Online (Sandbox Code Playgroud)

...?

Duk*_*uke 122

如果你使用jQuery,它就是用来参数化GET ajax请求的选项:

$.param( obj )
Run Code Online (Sandbox Code Playgroud)

http://api.jquery.com/jQuery.param/


ben*_*eet 105

优雅的:(假设您正在运行现代浏览器或节点)

var str = Object.keys(obj).map(function(key) {
  return key + '=' + obj[key];
}).join('&');
Run Code Online (Sandbox Code Playgroud)

与ES2017相当:(感谢Lukas)

let str = Object.entries(obj).map(([key, val]) => `${key}=${val}`).join('&');
Run Code Online (Sandbox Code Playgroud)

注意:encodeURIComponent()如果键/值不是URL编码,您可能希望使用.

  • 我只会改变`+ encodeURIComponent(obj [key])` (48认同)
  • 这是在ES2015`Object.entries(obj).map(([key,val])=> \`$ {key} = $ {val} \`).join('&')` (5认同)
  • 如果对象具有任何嵌套属性,则此操作将失败。 (2认同)
  • 要将ES2015答案编码为:== {encodeURIComponent(val)} (2认同)

aro*_*oth 90

var str = "";
for (var key in obj) {
    if (str != "") {
        str += "&";
    }
    str += key + "=" + encodeURIComponent(obj[key]);
}
Run Code Online (Sandbox Code Playgroud)

示例:http: //jsfiddle.net/WFPen/

  • @bobsoap:我认为@aroth有点领先于我,所以我会给@aroth所有其他相同的东西. (4认同)
  • @patrick - 完成:)荣誉是一项很好的运动. (4认同)
  • 为什么不使用递归函数? (3认同)
  • obj [key]不应该包含在encodeURIComponent()中吗?如果'somethingelse'是'某事和其他'会发生什么? (3认同)

u.k*_*u.k 23

ES6:

function params(data) {
  return Object.keys(data).map(key => `${key}=${encodeURIComponent(data[key])}`).join('&');
}

console.log(params({foo: 'bar'}));
console.log(params({foo: 'bar', baz: 'qux$'}));
Run Code Online (Sandbox Code Playgroud)


Luk*_*kas 20

ES2017方法

Object.entries(obj).map(([key, val]) => `${key}=${val}`).join('&')
Run Code Online (Sandbox Code Playgroud)

  • 这需要对键和值进行编码。请参阅重新encodeURIComponent的其他答案。 (3认同)
  • [ES2017](https://developer.mozilla.org/en-US/docs/Web/JavaScript/New_in_JavaScript/ECMAScript_Next_support_in_Mozilla),技术上。 (2认同)

ale*_*lex 18

一层深......

var serialiseObject = function(obj) {
    var pairs = [];
    for (var prop in obj) {
        if (!obj.hasOwnProperty(prop)) {
            continue;
        }
        pairs.push(prop + '=' + obj[prop]);
    }
    return pairs.join('&');
}
Run Code Online (Sandbox Code Playgroud)

jsFiddle.

谈论任意深度对象的递归函数......

var serialiseObject = function(obj) {
    var pairs = [];
    for (var prop in obj) {
        if (!obj.hasOwnProperty(prop)) {
            continue;
        }
        if (Object.prototype.toString.call(obj[prop]) == '[object Object]') {
            pairs.push(serialiseObject(obj[prop]));
            continue;
        }
        pairs.push(prop + '=' + obj[prop]);
    }
    return pairs.join('&');
}
Run Code Online (Sandbox Code Playgroud)

jsFiddle.

这当然意味着嵌套上下文在序列化中丢失了.

如果这些值不是以URL编码开头的,并且您打算在URL中使用它们,请查看JavaScript encodeURIComponent().


jfu*_*unk 9

这个怎么样?这是一行,没有依赖项:

new URLSearchParams(obj).toString();
// OUT: param1=something&param2=somethingelse&param3=another&param4=yetanother
Run Code Online (Sandbox Code Playgroud)

将其与内置的URL一起使用,如下所示:

let obj = { param1: 'something', param2: 'somethingelse', param3: 'another' }
obj[param4] = 'yetanother';
const url = new URL(`your_url.com`);
url.search = new URLSearchParams(obj);
const response = await fetch(url);
Run Code Online (Sandbox Code Playgroud)

  • 不适用于嵌套对象 (9认同)
  • 这是最好的答案 (4认同)

Yan*_*oto 6

仅供记录,如果您有支持ES6的浏览器,这里有一个解决方案reduce:

Object.keys(obj).reduce((prev, key, i) => (
  `${prev}${i!==0?'&':''}${key}=${obj[key]}`
), '');
Run Code Online (Sandbox Code Playgroud)

这是一个行动片段!

// Just for test purposes
let obj = {param1: 12, param2: "test"};

// Actual solution
let result = Object.keys(obj).reduce((prev, key, i) => (
  `${prev}${i!==0?'&':''}${key}=${obj[key]}`
), '');

// Run the snippet to show what happens!
console.log(result);
Run Code Online (Sandbox Code Playgroud)


Hen*_*nry 6

Object.keys(obj).map(k => `${encodeURIComponent(k)}=${encodeURIComponent(obj[k])}`).join('&')
Run Code Online (Sandbox Code Playgroud)


Jar*_*ish 5

由于我对递归函数做了大量的讨论,这是我自己的版本.

function objectParametize(obj, delimeter, q) {
    var str = new Array();
    if (!delimeter) delimeter = '&';
    for (var key in obj) {
        switch (typeof obj[key]) {
            case 'string':
            case 'number':
                str[str.length] = key + '=' + obj[key];
            break;
            case 'object':
                str[str.length] = objectParametize(obj[key], delimeter);
        }
    }
    return (q === true ? '?' : '') + str.join(delimeter);
}
Run Code Online (Sandbox Code Playgroud)

http://jsfiddle.net/userdude/Kk3Lz/2/

  • 只是一些随意的想法(a)`[]`优于`new Array()`(b)你可以使用`delimiter = delimiter || '&';`用于参数默认(并且拼写错误)(c)使用`for(in)`迭代将迭代所有可枚举属性,包括原型链上的东西(`obj.hasOwnProperty()`防范这个)(d)`typeof`可以*谎言*关于什么是东西,例如,如果使用`Number()`构造函数(e)构造,一些数字可以是`Object``Read`有一个`push()`方法添加成员(f)与"true"相比是多余的.我是一个挑剔的混蛋,但你想要反馈!:) (3认同)

Rob*_*lol 5

如果您使用的是 NodeJS 13.1 或更高版本,则可以使用本机 querystring 模块来解析查询字符串。

const qs = require('querystring');
let str = qs.stringify(obj)
Run Code Online (Sandbox Code Playgroud)