欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

npm qs模塊使用詳解

 更新時(shí)間:2020年02月07日 14:56:39   作者:__Amy  
這篇文章主要介紹了npm qs模塊使用詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

本文基本使用谷歌翻譯加上自己的理解,權(quán)當(dāng)加深記憶。

npm

簡(jiǎn)介

qs 是一個(gè)增加了一些安全性的查詢字符串解析和序列化字符串的庫(kù)。
主要維護(hù)者:Jordan Harband
最初創(chuàng)建者和維護(hù)者:TJ Holowaychuk

用法

var qs = require('qs');
var assert = require('assert');
 
var obj = qs.parse('a=c');
assert.deepEqual(obj, { a: 'c' });
 
var str = qs.stringify(obj);
assert.equal(str, 'a=c');

解析對(duì)象

qs.parse(string, [options]);

qs 允許在查詢字符串中使用[]的方式創(chuàng)建嵌套的對(duì)象。例如,字符串'foo[bar]=baz'可以轉(zhuǎn)換為:

  assert.deepEqual(qs.parse('foo[bar]=baz'), {
    foo: {
      bar: 'baz'
    }
  });

When using the plainObjects option the parsed value is returned as a null object, created via Object.create(null) and as such you should be aware that prototype methods will not exist on it and a user may set those names to whatever value they like:

  var nullObject = qs.parse('a[hasOwnProperty]=b', { plainObjects: true });
  assert.deepEqual(nullObject, { a: { hasOwnProperty: 'b' } });

By default parameters that would overwrite properties on the object prototype are ignored, if you wish to keep the data from those fields either use plainObjects as mentioned above, or set allowPrototypes to true which will allow user input to overwrite those properties. WARNING It is generally a bad idea to enable this option as it can cause problems when attempting to use the properties that have been overwritten. Always be careful with this option.

  var protoObject = qs.parse('a[hasOwnProperty]=b', { allowPrototypes: true });
  assert.deepEqual(protoObject, { a: { hasOwnProperty: 'b' } });

也可以解析 URI 編碼:

  assert.deepEqual(qs.parse('a%5Bb%5D=c'), {
    a: { b: 'c' }
  });

還可以像這樣嵌套對(duì)象:'foo[bar][baz]=foobarbaz':

  assert.deepEqual(qs.parse('foo[bar][baz]=foobarbaz'), {
    foo: {
      bar: {
        baz: 'foobarbaz'
      }
    }
  });

當(dāng)使用嵌套對(duì)象時(shí),qs 在默認(rèn)情況下最多解析到的深度是第五層(注:從第一個(gè)方括號(hào)到算起,到第五個(gè)方括號(hào)),例如嘗試解析一個(gè)這樣的字符串'a[b][c][d][e][f][g][h][i]=j'將會(huì)得到以下結(jié)果:

  var expected = {
    a: {
      b: {
        c: {
          d: {
            e: {
              f: {
                '[g][h][i]': 'j'
              }
            }
          }
        }
      }
    }
  };
  var string = 'a[b][c][d][e][f][g][h][i]=j';
  assert.deepEqual(qs.parse(string), expected);

可以給 qs.parse 傳遞一個(gè) depth 參數(shù)覆蓋默認(rèn)值:

var deep = qs.parse('a[b][c][d][e][f][g][h][i]=j', { depth: 1 });
assert.deepEqual(deep, { a: { b: { '[c][d][e][f][g][h][i]': 'j' } } });
 

當(dāng) qs 用于解析用戶輸入的時(shí)候,解析深度的限制有助于減輕用戶的濫用行為。最好將 depth 設(shè)置為一個(gè)合理的盡量小的數(shù)字。

出于類似的原因,qs 在默認(rèn)情況下最多解析 1000 個(gè)參數(shù)。通過(guò)傳遞 parameterLimit 參數(shù)可以修改默認(rèn)值:

  var limited = qs.parse('a=b&c=d', { parameterLimit: 1 });
  assert.deepEqual(limited, { a: 'b' });

忽略查詢字符串開(kāi)頭的 ? 可以使用 ignoreQueryPrefix:

  var prefixed = qs.parse('?a=b&c=d', { ignoreQueryPrefix: true });
  assert.deepEqual(prefixed, { a: 'b', c: 'd' });

還可以根據(jù)自定義的分隔符來(lái)解析 delimiter:

  var delimited = qs.parse('a=b;c=d', { delimiter: ';' });
  assert.deepEqual(delimited, { a: 'b', c: 'd' });

分隔符可以是正則表達(dá)式:

  var regexed = qs.parse('a=b;c=d,e=f', { delimiter: /[;,]/ });
  assert.deepEqual(regexed, { a: 'b', c: 'd', e: 'f' });

allowDots 選項(xiàng)可以啟用點(diǎn)表示法:

  var withDots = qs.parse('a.b=c', { allowDots: true });
  assert.deepEqual(withDots, { a: { b: 'c' } });

解析數(shù)組

qs 也可以用[]解析數(shù)組:

var withArray = qs.parse('a[]=b&a[]=c');
  assert.deepEqual(withArray, { a: ['b', 'c'] });

可以指定數(shù)組索引:

var withIndexes = qs.parse('a[1]=c&a[0]=b');
  assert.deepEqual(withIndexes, { a: ['b', 'c'] });

請(qǐng)注意,如果想要將字符串解析成數(shù)組而不是對(duì)象,那么[]之間的值必須是一個(gè)數(shù)字。 在創(chuàng)建具有特定索引的數(shù)組時(shí),qs會(huì)將稀疏數(shù)組壓縮為僅保留其順序的現(xiàn)有值:

var noSparse = qs.parse('a[1]=b&a[15]=c');
  assert.deepEqual(noSparse, { a: ['b', 'c'] });

空字符串也是一個(gè)值,并將被保留:

  var withEmptyString = qs.parse('a[]=&a[]=b');
  assert.deepEqual(withEmptyString, { a: ['', 'b'] });
  
  var withIndexedEmptyString = qs.parse('a[0]=b&a[1]=&a[2]=c');
  assert.deepEqual(withIndexedEmptyString, { a: ['b', '', 'c'] });

qs 還會(huì)限制數(shù)組最大索引為 20,任何索引大于20的數(shù)組成員都將被轉(zhuǎn)換為以索引為鍵的對(duì)象:

 var withMaxIndex = qs.parse('a[100]=b');
 assert.deepEqual(withMaxIndex, { a: { '100': 'b' } });

arrayLimit 選項(xiàng)可以修改默認(rèn)限制:

  var withArrayLimit = qs.parse('a[1]=b', { arrayLimit: 0 });
  assert.deepEqual(withArrayLimit, { a: { '1': 'b' } });

字符串不解析成數(shù)組,可以設(shè)置 parseArrays 為 false

  var noParsingArrays = qs.parse('a[]=b', { parseArrays: false });
  assert.deepEqual(noParsingArrays, { a: { '0': 'b' } });

如果混合使用兩種格式,qs 會(huì)將字符串解析為對(duì)象:

  var mixedNotation = qs.parse('a[0]=b&a[b]=c');
  assert.deepEqual(mixedNotation, { a: { '0': 'b', b: 'c' } });

也可以創(chuàng)建元素為對(duì)象的數(shù)組:

  var arraysOfObjects = qs.parse('a[][b]=c');
  assert.deepEqual(arraysOfObjects, { a: [{ b: 'c' }] });

序列化字符串

 qs.stringify(object, [options]);

默認(rèn)情況下,對(duì)象序列化后進(jìn)行URI編碼后輸出:

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

通過(guò)設(shè)置 encode 為 false 禁止 URI 編碼:

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

通過(guò)設(shè)置 encodeValuesOnly 為 true,可以禁用對(duì) key 進(jìn)行URI 編碼:

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

可以通過(guò)設(shè)置encoder 選項(xiàng)自定義編碼方式(注意:當(dāng) encode 被設(shè)置為 false 的時(shí)候,不適用):

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

與encoder 類似 decoder 可以用來(lái)解碼:

  var decoded = qs.parse('x=z', { decoder: function (str) {
    // Passed in values `x`, `z`
    return // Return decoded string
  }})

Examples beyond this point will be shown as though the output is not URI encoded for clarity. Please note that the return values in these cases will be URI encoded during real usage.

當(dāng)數(shù)組被序列化時(shí),默認(rèn)顯示索引:

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

 可以通過(guò)設(shè)置 indices 為 false 不顯示索引:

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

可以通過(guò)設(shè)置 arrayFormat 選項(xiàng)指定數(shù)組輸出格式:

  qs.stringify({ a: ['b', 'c'] }, { arrayFormat: 'indices' })
  // 'a[0]=b&a[1]=c'
  qs.stringify({ a: ['b', 'c'] }, { arrayFormat: 'brackets' })
  // 'a[]=b&a[]=c'
  qs.stringify({ a: ['b', 'c'] }, { arrayFormat: 'repeat' })
  // 'a=b&a=c'

對(duì)象序列化時(shí),默認(rèn)使用 [] 表示法:

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

通過(guò)設(shè)置 allowDots 為 true修改為點(diǎn)表示法:

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

空字符串和null值將被省略,但是=會(huì)保留:

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

沒(méi)有值的鍵將什么也不返回(例如空對(duì)象或數(shù)組):

  assert.equal(qs.stringify({ a: [] }), '');
  assert.equal(qs.stringify({ a: {} }), '');
  assert.equal(qs.stringify({ a: [{}] }), '');
  assert.equal(qs.stringify({ a: { b: []} }), '');
  assert.equal(qs.stringify({ a: { b: {}} }), '');

值為 undefined 的屬性將會(huì)被完全忽略:

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

addQueryPrefix 設(shè)置為 true可以在查詢字符串前面加 ?:

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

分隔符也可以設(shè)置:

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

如果只是序列化日期對(duì)象,可以使用 serializeDate 選項(xiàng):

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

可以使用 sort 選項(xiàng)來(lái)修改鍵的順序:

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

最后,可以使用 filter 選項(xiàng)過(guò)濾序列化輸出的鍵。如果給filter傳遞一個(gè)函數(shù),每個(gè)鍵調(diào)用一次該函數(shù)并用返回的值替換原來(lái)值。如果給filter傳遞一個(gè)數(shù)組,它將用于選擇對(duì)象的key和數(shù)組的索引:

  function filterFunc(prefix, value) {
    if (prefix == 'b') {
      // Return an `undefined` value to omit a property.
      return;
    }
    if (prefix == 'e[f]') {
      return value.getTime();
    }
    if (prefix == 'e[g][0]') {
      return value * 2;
    }
    return value;
  }
  qs.stringify({ a: 'b', c: 'd', e: { f: new Date(123), g: [2] } }, { filter: filterFunc });
  // 'a=b&c=d&e[f]=123&e[g][0]=4'
  qs.stringify({ a: 'b', c: 'd', e: 'f' }, { filter: ['a', 'e'] });
  // 'a=b&e=f'
  qs.stringify({ a: ['b', 'c', 'd'], e: 'f' }, { filter: ['a', 0, 2] });
  // 'a[0]=b&a[2]=d'

處理 null 值

默認(rèn)情況下,null 值被視為空對(duì)象:

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

解析字符串的時(shí)候并不會(huì)區(qū)分參數(shù)有沒(méi)有等號(hào),沒(méi)有值的話都會(huì)解析為空字符串:

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

要想?yún)^(qū)分空字符串和null值可以使用 strictNullHandling 選項(xiàng),序列化后的 null 值沒(méi)有=

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

要解析不帶 = 的值返回 null可以使用 strictNullHandling 選項(xiàng):

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

想要完全跳過(guò)值為 null 的鍵不解析,可以使用 skipNulls 選項(xiàng):

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

處理特殊字符集:

默認(rèn)情況下,字符的編碼和解碼在utf-8中完成。 如果希望將查詢字符串編碼為不同的字符集(i.e.Shift JIS),您可以使用qs-iconv庫(kù):

  var encoder = require('qs-iconv/encoder')('shift_jis');
  var shiftJISEncoded = qs.stringify({ a: 'こんにちは!' }, { encoder: encoder });
  assert.equal(shiftJISEncoded, 'a=%82%B1%82%F1%82%C9%82%BF%82%CD%81I');
 

這也適用于解碼查詢字符串:

 var decoder = require('qs-iconv/decoder')('shift_jis');
  var obj = qs.parse('a=%82%B1%82%F1%82%C9%82%BF%82%CD%81I', { decoder: decoder });
  assert.deepEqual(obj, { a: 'こんにちは!' });
 

RFC 3986 and RFC 1738 space encoding

RFC3986 used as default option and encodes ' ' to %20 which is backward compatible. In the same time, output can be stringified as per RFC1738 with ' ' equal to ‘+'.

  

assert.equal(qs.stringify({ a: 'b c' }), 'a=b%20c');
 assert.equal(qs.stringify({ a: 'b c' }, { format : 'RFC3986' }), 'a=b%20c');
 assert.equal(qs.stringify({ a: 'b c' }, { format : 'RFC1738' }), 'a=b+c');

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

最新評(píng)論