对象序列化并以&拼接

2018-09-21

有一个需求是将对象转化成字符串并以&连接

问题描述

{
  name:ChangJun,
  age:21,
  number:2016002448
}

需要返回

name=changjun&age=21&number=2016002448

我的思路


当有这个需求的时候我就马上想到了qs.stringify()这个方法,在请求的时候我们经常会利用这个方法将对象序列化url的形式并以&拼接,同时比较常用的还有qs.parse()这个方法,将url解析成对象的形式。有了想法之后当然马上就写在我的方法里了。起初还真的并未发现什么问题,因为在最初尝试里返回的始终都是自己想要的。可是,当我们在要序列化的对象里出现一些字符时,例如:

{
  token:'sdjasidnasdna*Jas*',
  name:'chang'
}

我们想象中应该会返回

token=sdjasidnasdna*Jas*&name=chang

那么事实中是这样吗,不是的我们可以看到在控制台给我们返回的结果是这样的。

token=sdjasidnasdna%Jas%&name=chang

就其中的几个字符有差别,该场景用于前后端加密时,如果不细细一一对比,还真的很难发现原来是因为几个字符的问题。但该问题出现时,最快的解决办法就是自己写一个方法去进行序列化对象并以&拼接。为了马上向解决问题,就动手写一个方法

const objToStr = obj =>{
  let arr = []
  Object.keys(obj).forEach(key => {
    arr.push(key + '=' + obj[key])
  });
  return arr.join('&')
}

方法就不多说了,大家看一下就明白,那么此时问题虽然解决了,我们还是回归到原来在使用qs.strinfly上为什么会在序列化对象时,字符串发生变化。那么首先先思考一下,qs.strinfly是为了序列化对象以url的形式,那么此时我们应该能联想到它应该是跟url相关,然后查阅其文档不难发现,该方法默认是以url编码形式进行序列化,因此一些不属于url允许的字符会被转化,关于url编码大家可以自行查看。那么搞清楚为什么之后,我们来看一下有没有什么方法解决。

解决办法


在使用这些库的方法时,很容易的就可以想到肯定会有可选参数。那么查文档可以很快发现,我们可以设置取消默认编码的方式。在调用该方法时将编码方式设置成false

qs.stringify(obj, { encode: false })

此时调用就会发现我们的结果就是我们想要的结果了。

相关文档

  1. npm qs ([https://github.com/ljharb/qs])
  2. url 编码 (https://www.cnblogs.com/liuhongfeng/p/5006341.html