JavaScript对象的查询字符串编码

719

有没有一种快速简单的方法将JavaScript对象编码为可以通过GET请求传递的string

不使用jQuery或其他框架,只需使用纯JavaScript :)


1
如果有合适的解决方案,为什么不能使用jQuery呢? - eaglei22
5
因为当时我正在为一款IPTV机顶盒设备开发项目工作,不允许使用外部库。;-) - napolux
1
感谢回复。我经常看到这个规范,一直想知道何时会使用。现在,我有一个例子了,谢谢! :) - eaglei22
24
因为有时候你不想加载一个庞大的库来获取一个id元素。 - Aaron Butacov
我制作了一个用于将JSON转换为HTTPs查询的网站:https://kshitijdhyani.com/JSONtoHTTPSerializer/ 希望对你有所帮助。 - Kshitij Dhyani
显示剩余3条评论
49个回答

1
我已经为此编写了一个包:object-query-string :)
它支持嵌套对象、数组、自定义编码函数等,非常轻量级,无需使用jQuery。
// TypeScript
import { queryString } from 'object-query-string';

// Node.js
const { queryString } = require("object-query-string");

const query = queryString({
    filter: {
        brands: ["Audi"],
        models: ["A4", "A6", "A8"],
        accidentFree: true
    },
    sort: 'mileage'
});


返回
filter[brands][]=Audi&filter[models][]=A4&filter[models][]=A6&filter[models][]=A8&filter[accidentFree]=true&sort=milage

1

使用:

const objectToQueryParams = (o = {}) =>
  Object.entries(o)
    .map((p) => `${encodeURIComponent(p[0])}=${encodeURIComponent(p[1])}`)
    .join("&");

请参考下面的代码片段获取更多信息: https://gist.github.com/bhaireshm


1

将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://dev59.com/enI-5IYBdhLWcg3wta1q#1714899
 */
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("&");
};

0

另一种方法(无递归对象):

   getQueryString = function(obj)
   {
      result = "";

      for(param in obj)
         result += ( encodeURIComponent(param) + '=' + encodeURIComponent(obj[param]) + '&' );

      if(result) //it's not empty string when at least one key/value pair was added. In such case we need to remove the last '&' char
         result = result.substr(0, result.length - 1); //If length is zero or negative, substr returns an empty string [ref. http://msdn.microsoft.com/en-us/library/0esxc5wy(v=VS.85).aspx]

      return result;
   }

alert( getQueryString({foo: "hi there", bar: 123, quux: 2 }) );

0

参考用户187291的答案,添加"isArray"作为参数,使JSON嵌套数组可以被转换。

data : {
    staffId : "00000001",
    Detail : [ {
        "identityId" : "123456"
    }, {
        "identityId" : "654321"
    } ],

}

为了得到结果,

staffId=00000001&Detail[0].identityId=123456&Detail[1].identityId=654321

使用:

serialize = function(obj, prefix, isArray) {
    var str = [], p = 0;
    for (p in obj) {
        if (obj.hasOwnProperty(p)) {
            var k, v;
            if (isArray)
                k = prefix ? prefix + "[" + p + "]" : p, v = obj[p];
            else
                k = prefix ? prefix + "." + p + "" : p, v = obj[p];

            if (v !== null && typeof v === "object") {
                if (Array.isArray(v)) {
                    serialize(v, k, true);
                } else {
                    serialize(v, k, false);
                }
            } else {
                var query = k + "=" + v;
                str.push(query);
            }
        }
    }
    return str.join("&");
};

serialize(data, "prefix", false);

0

使用reduce编码对象为查询字符串的实现:

export const encodeAsQueryString = (params) => (
  Object.keys(params).reduce((acc, key)=>(
    params.hasOwnProperty(key) ? (
      [...acc, encodeURIComponent(key) + '=' + encodeURIComponent(params[key])]
    ) : acc
  ), []).join('&')
);

0
如果您想将整个对象作为单个参数传递,例如:?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"}

如何使用?不知道怎么用。 - Nelson Javier Avila

0
这是一个简单的实现,它获取一个对象并将其转换为查询参数字符串:
export function objectToQueryParams(queryParams: object): string {
  return queryParams ?
    Object.entries(queryParams).reduce((acc, [key, val], index) => {
      const sign = index === 0 ? '?' : '&';
      acc += `${sign}${encodeURIComponent(key)}=${encodeURIComponent(val)}`;
      return acc;
    }, '')
    : '';
}

1
你需要在 keyval 周围使用 encodeURIComponent,就像这里的其他响应一样。 - sbk

-1

只需使用以下内容:

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)


-1
 let data = {
    id:1,
    name:'Newuser'
    };
const getqueryParam = data => {
  let datasize = Object.keys(data).length;
  let initial = '?';

  Object.keys(data).map(function (key, index) {
    initial = initial.concat(`${key}=${data[key]}`);
    index != datasize - 1 && (initial = initial.concat('&'));
  });
  console.log(initial, 'MyqueryString');
  return initial;
};

console.log(getqueryParam(data))//You can get the query string here

If you have baseUrl means to get full query use 

baseUrl.concat(getqueryParam(data))


1
你的回答可以通过提供更多支持信息来改进。请编辑以添加进一步的细节,例如引用或文档,以便他人可以确认你的答案是正确的。您可以在帮助中心找到有关如何编写良好答案的更多信息。 - Community

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接