当前位置:   article > 正文

axios post请求参数传输表单数据,其中一个key的value需要json格式, (qs的使用知识扩充)_post请求 key value

post请求 key value

今天遇到了一个场景,post请求,请求体的content-type是application/x-www-form-urlencoded,然后我按照往常的情况直接设置完,接口参数进行qs.stringify操作。转成表单的格式传输给后端,但是在浏览器中查看接口参数发现是这样子的:

因为我参数中answerMap是一个对象,qs直接把这个answerMap的值给拆分了,但是后端要求answerMap的值是json,所以我在给接口传参前讲answerMap的值用JSON.stringify转化了一下,这样子qs就把整体当做一个value去操作。

接下来是对qs使用的扩展知识:

 在项目开发中,发现qs.stringify会导致*特殊符号转义,导致页面处理正常逻辑时报错。例如,

  1. let obj = {
  2. a: 1,
  3. b: '*2*',
  4. c: '123',
  5. e: true,
  6. f: null,
  7. d: undefined,
  8. h: NaN
  9. }
  10. console.log(qs.stringify(obj)); //a=1&b=%2A2%2A&c=123&e=true&f&h=NaN

实际上我们想要的结果是a=1&b=*2*&c=123&e=true&f&h=NaN,这时候可以在options中配置{ encode: false }来实现

console.log(qs.stringify(obj, { encode: false }));//a=1&b=*2*&c=123&e=true&f&h=NaN
Stringifying字符串化详细用法
1.编码

字符串化时,默认情况下,qs对输出进行URI编码。对象的字符串化与您预期的一样:

  1. assert.equal(qs.stringify({ a: 'b' }), 'a=b');
  2. assert.equal(qs.stringify({ a: { b: 'c' } }), 'a%5Bb%5D=c');

可以通过将encode选项设置为false来禁用此编码:

  1. var unencoded = qs.stringify({ a: { b: 'c' } }, { encode: false });
  2. assert.equal(unencoded, 'a[b]=c');

通过将encodeValuesOnly选项设置为true,可以禁用密钥的编码:

  1. var encodedValues = qs.stringify(
  2. { a: 'b', c: ['d', 'e=f'], f: [['g'], ['h']] },
  3. { encodeValuesOnly: true }
  4. );
  5. assert.equal(encodedValues,'a=b&c[0]=d&c[1]=e%3Df&f[0][0]=g&f[1][0]=h');

此编码也可以由设置为encoder选项的自定义编码方法替换:

  1. var encoded = qs.stringify({ a: { b: 'c' } }, { encoder: function (str) {
  2. // Passed in values `a`, `b`, `c`
  3. return // Return encoded string
  4. }})

您可以使用提供给编码器的类型参数,使用不同的逻辑对键和值进行编码:

  1. var encoded = qs.stringify({ a: { b: 'c' } }, { encoder: function (str, defaultEncoder, charset, type) {
  2. if (type === 'key') {
  3. return // Encoded key
  4. } else if (type === 'value') {
  5. return // Encoded value
  6. }
  7. }})
2.数组

当数组被字符串化时,它们遵循arrayFormat选项,默认为indices

  1. qs.stringify({ a: ['b', 'c', 'd'] });
  2. // 'a[0]=b&a[1]=c&a[2]=d'

您可以通过将indices选项设置为false或更明确地将arrayFormat选项设置为repeat来覆盖此设置:

  1. qs.stringify({ a: ['b', 'c', 'd'] }, { indices: false });
  2. // 'a=b&a=c&a=d'

您可以使用arrayFormat选项来指定输出数组的格式:

  1. qs.stringify({ a: ['b', 'c'] }, { arrayFormat: 'indices' })
  2. // 'a[0]=b&a[1]=c'
  3. qs.stringify({ a: ['b', 'c'] }, { arrayFormat: 'brackets' })
  4. // 'a[]=b&a[]=c'
  5. qs.stringify({ a: ['b', 'c'] }, { arrayFormat: 'repeat' })
  6. // 'a=b&a=c'
  7. qs.stringify({ a: ['b', 'c'] }, { arrayFormat: 'comma' })
  8. // 'a=b,c'
3.对象

当对象被字符串化时,默认情况下它们使用括号表示法:

  1. qs.stringify({ a: { b: { c: 'd', e: 'f' } } });
  2. // 'a[b][c]=d&a[b][e]=f'

您可以通过将allowDots选项设置为true来覆盖此设置以使用点表示法:

  1. qs.stringify({ a: { b: { c: 'd', e: 'f' } } }, { allowDots: true });
  2. // 'a.b.c=d&a.b.e=f'

您可以通过将allowEmptyArrays选项设置为true来允许空数组值:

  1. qs.stringify({ foo: [], bar: 'baz' }, { allowEmptyArrays: true });
  2. // 'foo[]&bar=baz'

空字符串和null值将忽略该值,但等号(=)仍保留:

assert.equal(qs.stringify({ a: '' }), 'a=');

没有值的键(例如空对象或数组)将不返回任何内容:

  1. assert.equal(qs.stringify({ a: [] }), '');
  2. assert.equal(qs.stringify({ a: {} }), '');
  3. assert.equal(qs.stringify({ a: [{}] }), '');
  4. assert.equal(qs.stringify({ a: { b: []} }), '');
  5. assert.equal(qs.stringify({ a: { b: {}} }), '');

设置为undefined的属性将被完全忽略:

assert.equal(qs.stringify({ a: null, b: undefined }), 'a=');

查询字符串可以有选择地在前面加上问号:

assert.equal(qs.stringify({ a: 'b', c: 'd' }, { addQueryPrefix: true }), '?a=b&c=d');

也可以用stringify覆盖该函数:

assert.equal(qs.stringify({ a: 'b', c: 'd' }, { delimiter: ';' }), 'a=b;c=d');

如果你只想覆盖Date对象的序列化,你可以提供一个serializeDate选项:

  1. var date = new Date(7);
  2. assert.equal(qs.stringify({ a: date }), 'a=1970-01-01T00:00:00.007Z'.replace(/:/g, '%3A'));
  3. assert.equal(
  4. qs.stringify({ a: date }, { serializeDate: function (d) { return d.getTime(); } }),
  5. 'a=7'
  6. );

您可以使用sort选项来影响参数键的顺序:

  1. function alphabeticalSort(a, b) {
  2. return a.localeCompare(b);
  3. }
  4. assert.equal(qs.stringify({ a: 'c', z: 'y', b : 'f' }, { sort: alphabeticalSort }), 'a=c&b=f&z=y');

最后,您可以使用filter选项来限制字符串化输出中包含哪些键。 如果你传递一个函数,它将为每个键调用以获得替换值。否则你 传递一个数组,它将用于选择属性和数组索引进行字符串化:

  1. function filterFunc(prefix, value) {
  2. if (prefix == 'b') {
  3. // Return an `undefined` value to omit a property.
  4. return;
  5. }
  6. if (prefix == 'e[f]') {
  7. return value.getTime();
  8. }
  9. if (prefix == 'e[g][0]') {
  10. return value * 2;
  11. }
  12. return value;
  13. }
  14. qs.stringify({ a: 'b', c: 'd', e: { f: new Date(123), g: [2] } }, { filter: filterFunc });
  15. // 'a=b&c=d&e[f]=123&e[g][0]=4'
  16. qs.stringify({ a: 'b', c: 'd', e: 'f' }, { filter: ['a', 'e'] });
  17. // 'a=b&e=f'
  18. qs.stringify({ a: ['b', 'c', 'd'], e: 'f' }, { filter: ['a', 0, 2] });
  19. // 'a[0]=b&a[2]=d'
4.Handling of 处理 null values 值

默认情况下,null值被视为空字符串:

  1. var withNull = qs.stringify({ a: null, b: '' });
  2. assert.equal(withNull, 'a=&b=');

解析不区分带等号和不带等号的参数。两者都转换为空字符串。

  1. var equalsInsensitive = qs.parse('a&b=');
  2. assert.deepEqual(equalsInsensitive, { a: '', b: '' });

要区分null值和空字符串,请使用strictNullHandling标志。在结果字符串中, 值没有null符号:

  1. var strictNull = qs.stringify({ a: null, b: '' }, { strictNullHandling: true });
  2. assert.equal(strictNull, 'a&b=');

要将没有=的值解析回null,请使用strictNullHandling标志:

  1. var parsedStrictNull = qs.parse('a&b=', { strictNullHandling: true });
  2. assert.deepEqual(parsedStrictNull, { a: null, b: '' });

要完全跳过具有null值的渲染关键帧,请使用skipNulls标志:

  1. var nullsSkipped = qs.stringify({ a: 'b', c: null}, { skipNulls: true });
  2. assert.equal(nullsSkipped, 'a=b');

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家小花儿/article/detail/1007041
推荐阅读
相关标签
  

闽ICP备14008679号