Javascript 如何将对象序列化为 URL 查询参数列表?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6566456/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 22:19:22  来源:igfitidea点击:

How to serialize an Object into a list of URL query parameters?

javascript

提问by bobsoap

Without knowing the keys of a JavaScript Object, how can I turn something like...

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

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

obj[param4] = 'yetanother';

...into...

...进入...

var str = 'param1=something&param2=somethingelse&param3=another&param4=yetanother';

...?

……?

采纳答案by aroth

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

Example: http://jsfiddle.net/WFPen/

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

回答by Duke

If you use jQuery, this is what it uses for parameterizing the options of a GET ajax request:

如果您使用 jQuery,这就是它用于参数化 GET ajax 请求的选项的内容:

$.param( obj )

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

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

回答by benweet

An elegant one: (assuming you are running a modern browser or node)

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

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

And the ES2017 equivalent: (thanks to Lukas)

和 ES2017 等效:(感谢 Lukas)

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

Note:You probably want to use encodeURIComponent()if the keys/values are not URL encoded.

注意:encodeURIComponent()如果键/值不是 URL 编码的,您可能想要使用。

回答by jfunk

How about this? It is one line and no dependencies:

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

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

Use it with the URL builtin like so:

将它与内置的 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);

[Edit April 4, 2020]: as mentioned in the comments nullvalues will be interpreted as a string 'null'. So be careful with null values.

[编辑 2020 年 4 月 4 日]:如评论中所述,null值将被解释为 string 'null'。所以要小心空值。

回答by u.k

ES6:

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$'}));

回答by Lukas

ES2017 approach

ES2017 方法

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

回答by alex

For one level deep...

对于一层深...

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

jsFiddle.

js小提琴

There was talk about a recursive function for arbitrarily deep objects...

有关于任意深度对象的递归函数的讨论......

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('&');
}

jsFiddle.

js小提琴

This of course means that the nesting context is lost in the serialisation.

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

If the values are not URL encoded to begin with, and you intend to use them in a URL, check out JavaScript's encodeURIComponent().

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

回答by Henry

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

回答by Yan Foto

Just for the record and in case you have a browser supporting ES6, here's a solution with reduce:

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

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

And here's a snippet in action!

这是一个正在运行的片段!

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

回答by Jared Farrish

Since I made such a big deal about a recursive function, here is my own version.

由于我对递归函数做了如此大的处理,这里是我自己的版本。

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

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

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