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

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


当前回答

只需使用以下方法:

encodeURIComponent(JSON.stringify(obj))

// elastic search example let story ={ "query": { "bool": { "must": [ { "term": { "revision.published": 0, } }, { "term": { "credits.properties.by.properties.name": "Michael Guild" } }, { "nested": { "path": "taxonomy.sections", "query": { "bool": { "must": [ { "term": { "taxonomy.sections._id": "/science" } }, { "term": { "taxonomy.sections._website": "staging" } } ] } } } } ] } } } const whateva = encodeURIComponent(JSON.stringify(story)) console.log(whateva)

其他回答

下面是Object.entries的简洁递归版本。它处理任意嵌套的数组,但不处理嵌套的对象。它还会删除空元素:

const format = (k,v) => v !== null ? `${k}=${encodeURIComponent(v)}` : ''

const to_qs = (obj) => {
    return [].concat(...Object.entries(obj)
                       .map(([k,v]) => Array.isArray(v) 
                          ? v.map(arr => to_qs({[k]:arr})) 
                          : format(k,v)))
           .filter(x => x)
           .join('&');
}

例如:

let json = { 
    a: [1, 2, 3],
    b: [],              // omit b
    c: 1,
    d: "test&encoding", // uriencode
    e: [[4,5],[6,7]],   // flatten this
    f: null,            // omit nulls
    g: 0
};

let qs = to_qs(json)

=> "a=1&a=2&a=3&c=1&d=test%26encoding&e=4&e=5&e=6&e=7&g=0"

这个函数跳过null/undefined值

export function urlEncodeQueryParams(data) {
    const params = Object.keys(data).map(key => data[key] ? `${encodeURIComponent(key)}=${encodeURIComponent(data[key])}` : '');
    return params.filter(value => !!value).join('&');
}

这是一个开箱即用的。net后端解决方案。我已经采取了这个线程的主要答案,并更新它以适应我们的。net需求。

function objectToQuerystring(params) {
var result = '';

    function convertJsonToQueryString(data, progress, name) {
        name = name || '';
        progress = progress || '';
        if (typeof data === 'object') {
            Object.keys(data).forEach(function (key) {
                var value = data[key];
                if (name == '') {
                    convertJsonToQueryString(value, progress, key);
                } else {
                    if (isNaN(parseInt(key))) {
                        convertJsonToQueryString(value, progress, name + '.' + key);
                    } else {
                        convertJsonToQueryString(value, progress, name + '[' + key+ ']');
                    }
                }
            })
        } else {
            result = result ? result.concat('&') : result.concat('?');
            result = result.concat(`${name}=${data}`);
        }
    }

    convertJsonToQueryString(params);
    return result;
}

在讨论了一些最重要的答案之后,我编写了另一个实现,它也可以处理一些边缘情况

function serialize(params, prefix) {                
    return Object.entries(params).reduce((acc, [key, value]) => {
        // remove whitespace from both sides of the key before encoding
        key = encodeURIComponent(key.trim());

        if (params.constructor === Array ) {
          key = `${prefix}[]`;
        } else if (params.constructor === Object) {
          key = (prefix ? `${prefix}[${key}]` : key);
        }

        /**
         *  - undefined and NaN values will be skipped automatically
         *  - value will be empty string for functions and null
         *  - nested arrays will be flattened
         */
        if (value === null || typeof value === 'function') {
            acc.push(`${key}=`);
        } else if (typeof value === 'object') {
            acc = acc.concat(serialize(value, key));
        } else if(['number', 'boolean', 'string'].includes(typeof value) && value === value) { // self-check to avoid NaN
            acc.push(`${key}=${encodeURIComponent(value)}`);
        }

        return acc;
    }, []);
}

function objectToQueryString(queryParameters) {
    return queryParameters ? serialize(queryParameters).join('&'): '';
}

let x = objectToQueryString({
    foo: 'hello world',
    bar: {
      blah: 123,
      list: [1, 2, 3],
        'nested array': [[4,5],[6,7]] // will be flattened
    },
    page: 1,
    limit: undefined, // field will be ignored
    check: false,
    max: NaN, // field will be ignored
    prop: null,
    ' key value': 'with spaces' // space in key will be trimmed out
});
  
console.log(x); // foo=hello%20world&bar[blah]=123&bar[list][]=1&bar[list][]=2&bar[list][]=3&bar[nested%20array][][]=4&bar[nested%20array][][]=5&bar[nested%20array][][]=6&bar[nested%20array][][]=7&page=1&check=false&prop=&key%20value=with%20spaces

PHP符号的TypeScript版本(没有URL转义版本)

/**
 * Converts an object into a Cookie-like string.
 * @param toSerialize object or array to be serialized
 * @param prefix used in deep objects to describe the final query parameter
 * @returns ampersand separated key=value pairs
 *
 * Example:
 * ```js
 * serialize({hello:[{world: "nice"}]}); // outputs  "hello[0][world]=nice"
 * ```
 * ---
 * Adapted to TS from a StackOverflow answer https://stackoverflow.com/a/1714899/4537906
 */
const serialize = (toSerialize: unknown = {}, prefix?: string) => {
  const keyValuePairs = [];

  Object.keys(toSerialize).forEach((attribute) => {
    if (Object.prototype.hasOwnProperty.call(toSerialize, attribute)) {
      const key = prefix ? `${prefix}[${attribute}]` : attribute;
      const value = toSerialize[attribute];
      const toBePushed =
        value !== null && typeof value === "object"
          ? serialize(value, key)
          : `${key}=${value}`;
      keyValuePairs.push(toBePushed);
    }
  });

  return keyValuePairs.join("&");
};