将JavaScript对象转换为URL参数

39

我意识到,从根本上讲,我可能正在错误的方向上着手处理这个问题,因此我开放接受任何正确方向上的推动。

我试图使用HipChat API向一个房间发送通知,像这样:

https://www.hipchat.com/docs/api/method/rooms/message

我正试图使用一个js对象的参数来构建示例中的URL,所以基本上我正在尝试转换这个:

var hipChatSettings = {
            format:"json",
            auth_token:token,
            room_id: 1,
            from: "Notifications",
            message: "Message"
        }

变成了这样:

https://api.hipchat.com/v1/rooms/message?format=json&auth_token=token&room_id=1&from=Notifications&message=Message


可能是重复的问题:如何将对象序列化为参数列表? - Koen.
5个回答

51

您应该检查这个jQuery.param函数

var params = { width:1680, height:1050 };
var str = jQuery.param( params );
console.log(str);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>


(我应该说明我正在使用jQuery,但你显然读懂了我的想法):) - user2865446
13
他并没有读懂你的想法。只是在Stack Overflow上,当你询问有关JavaScript的问题时,即使你明确表示不想要jQuery答案,你也会得到90个jQuery答案。记住这一点,当你想要一个非jQuery的JavaScript答案时,请注意这一点。 ;) - L0j1k
@L0j1k 你说得对,但是jQuery的答案对于从谷歌搜索到这里的其他人可能也有用,即使对于OP来说是无用的。所以我认为这是一个好的做法。 - Vadim Ovchinnikov
他没有读取你的思维,而是查看了你的关键词。因此,这种做法没有触发我通常会给出的贬值。 - Adrian Bartholomew
@AdrianBartholomew 我猜你所说的“关键词”是指标签,但是直到这个回答发布之后才添加了jQuery标签。 - Elezar
我没算过时间,但是……我不想点踩的心情 :-) - Adrian Bartholomew

46
Object.keys(hipChatSettings).map(function(k) {
    return encodeURIComponent(k) + "=" + encodeURIComponent(hipChatSettings[k]);
}).join('&')
// => "format=json&auth_token=token&room_id=1&from=Notifications&message=Message"

警告:这段 JavaScript 较新。如果你想让它在旧版浏览器上工作,请使用兼容库或将其改写为for循环。


13

这样的东西可能适合你

var str = "?" + Object.keys(hipChatSettings).map(function(prop) {
  return [prop, hipChatSettings[prop]].map(encodeURIComponent).join("=");
}).join("&");

// "?format=json&auth_token=token&room_id=1&from=Notifications&message=Message"

如果您无法使用ECMAScript 5,可以使用简单的for循环

var pairs = [];

for (var prop in hipChatSettings) {
  if (hipChatSettings.hasOwnProperty(prop)) {
    var k = encodeURIComponent(prop),
        v = encodeURIComponent(hipChatSettings[prop]);
    pairs.push( k + "=" + v);
  }
}

var str = "?" + pairs.join("&");

2
我喜欢这个答案。对于ES6,你可以进一步调整为function makeParams(params) => { return params ? '?' + Object.keys(params).map((key) => ([key, params[key]].map(encodeURIComponent).join("="))).join("&") : '' },然后你只需要将其附加到你的路径上,path + makeParams(params),它会处理未定义、null和{} - jlyonsmith

4
来晚了,但我很喜欢这个简洁明了的内容:
  Object.entries(hipChatSettings)
    .map(
      ([key, val]) => `${encodeURIComponent(key)}=${encodeURIComponent(val)}`
    )
    .join("&");

4

ES6版本可以处理具有嵌套数组的对象

encodeURI(getUrlString({a: 1, b: [true, 12.3, "string"]}))

对于上述代码,返回编码后的URI字符串。
getUrlString (params, keys = [], isArray = false) {
  const p = Object.keys(params).map(key => {
    let val = params[key]

    if ("[object Object]" === Object.prototype.toString.call(val) || Array.isArray(val)) {
      if (Array.isArray(params)) {
        keys.push("")
      } else {
        keys.push(key)
      }
      return getUrlString(val, keys, Array.isArray(val))
    } else {
      let tKey = key

      if (keys.length > 0) {
        const tKeys = isArray ? keys : [...keys, key]
        tKey = tKeys.reduce((str, k) => { return "" === str ? k : `${str}[${k}]` }, "")
      }
      if (isArray) {
        return `${ tKey }[]=${ val }`
      } else {
        return `${ tKey }=${ val }`
      }

    }
  }).join('&')

  keys.pop()
  return p
}

实际上只有这个答案适用于多层嵌套的对象/数组,除了jQuery之外,但如果仅用于此单一目的,则jQuery库太大。 - Titenis
嵌套对象使用效果非常好,这是我找到的最佳方法,我只添加了encodeURIComponent(val)。 - Juan Angel

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