最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

npm qs模塊使用詳解

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

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

npm

簡介

qs 是一個增加了一些安全性的查詢字符串解析和序列化字符串的庫。
主要維護者:Jordan Harband
最初創(chuàng)建者和維護者: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');

解析對象

qs.parse(string, [options]);

qs 允許在查詢字符串中使用[]的方式創(chuàng)建嵌套的對象。例如,字符串'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' }
  });

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

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

當使用嵌套對象時,qs 在默認情況下最多解析到的深度是第五層(注:從第一個方括號到算起,到第五個方括號),例如嘗試解析一個這樣的字符串'a[b][c][d][e][f][g][h][i]=j'將會得到以下結(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 傳遞一個 depth 參數(shù)覆蓋默認值:

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' } } });
 

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

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

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

忽略查詢字符串開頭的 ? 可以使用 ignoreQueryPrefix:

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

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

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

分隔符可以是正則表達式:

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

allowDots 選項可以啟用點表示法:

  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'] });

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

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

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

  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 還會限制數(shù)組最大索引為 20,任何索引大于20的數(shù)組成員都將被轉(zhuǎn)換為以索引為鍵的對象:

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

arrayLimit 選項可以修改默認限制:

  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 會將字符串解析為對象:

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

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

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

序列化字符串

 qs.stringify(object, [options]);

默認情況下,對象序列化后進行URI編碼后輸出:

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

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

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

通過設(shè)置 encodeValuesOnly 為 true,可以禁用對 key 進行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');

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

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

與encoder 類似 decoder 可以用來解碼:

  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.

當數(shù)組被序列化時,默認顯示索引:

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

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

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

可以通過設(shè)置 arrayFormat 選項指定數(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'

對象序列化時,默認使用 [] 表示法:

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

通過設(shè)置 allowDots 為 true修改為點表示法:

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

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

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

沒有值的鍵將什么也不返回(例如空對象或數(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 的屬性將會被完全忽略:

  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');

如果只是序列化日期對象,可以使用 serializeDate 選項:

  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 選項來修改鍵的順序:

  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 選項過濾序列化輸出的鍵。如果給filter傳遞一個函數(shù),每個鍵調(diào)用一次該函數(shù)并用返回的值替換原來值。如果給filter傳遞一個數(shù)組,它將用于選擇對象的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 值

默認情況下,null 值被視為空對象:

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

解析字符串的時候并不會區(qū)分參數(shù)有沒有等號,沒有值的話都會解析為空字符串:

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

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

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

要解析不帶 = 的值返回 null可以使用 strictNullHandling 選項:

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

想要完全跳過值為 null 的鍵不解析,可以使用 skipNulls 選項:

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

處理特殊字符集:

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

  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');

以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • javascript 改變網(wǎng)頁加載的CSS

    javascript 改變網(wǎng)頁加載的CSS

    javascript 改變網(wǎng)頁加載的CSS主要通過動態(tài)響應(yīng)select觸發(fā)的選項變化控制link標簽加載的css,以實現(xiàn)不依賴cookie控制的頁面css樣式動態(tài)加載功能,需要的朋友可以參考一下
    2007-12-12
  • JS設(shè)計模式之中介者模式使用方法詳解

    JS設(shè)計模式之中介者模式使用方法詳解

    JavaScript中介者模式是一種行為型設(shè)計模式,用于降低多個對象之間的耦合性,在中介者模式中,多個對象之間不直接相互通信,而是通過中介者進行通信, 本文就來給大家詳細的介紹一下JS設(shè)計模式之中介者模式使用方法,需要的朋友可以參考下
    2023-08-08
  • 多瀏覽器兼容的動態(tài)加載 JavaScript 與 CSS

    多瀏覽器兼容的動態(tài)加載 JavaScript 與 CSS

    Omar AL Zabir這位MVP總是喜歡搞些稀奇古怪同時又很實用的小東西,并且還十分值得參考。最近他就做了一個叫做ensure的小工具用于動態(tài)加載JavaScript、CSS與HTML,而且IE、Firefox、Opera、Safari都支持了,那么我們就來看看ensure是如何做到動態(tài)加載JavaScript與CSS的。
    2008-09-09
  • 封裝好的javascript前端分頁插件pagination

    封裝好的javascript前端分頁插件pagination

    本文給大家分享一個非常不錯的封裝好的javascript前端分頁插件pagination,不依賴任何庫,有很高的擴展性,有需要的小伙伴可以參考下。
    2016-01-01
  • 談?wù)凧avaScript中的函數(shù)

    談?wù)凧avaScript中的函數(shù)

    這篇文章主要介紹了JavaScript中的函數(shù)的相關(guān)資料,幫助大家更好的理解和學習JavaScript,感興趣的朋友可以了解下
    2020-09-09
  • JavaScript實現(xiàn)各種排序的代碼詳解

    JavaScript實現(xiàn)各種排序的代碼詳解

    這篇文章給大家介紹了js實現(xiàn)各種排序功能,包括冒泡排序,選擇排序和插入排序,代碼簡單易懂,非常不錯,具有參考借鑒價值,需要的的朋友參考下吧
    2017-08-08
  • JavaScript中的

    JavaScript中的"=、==、==="區(qū)別講解

    今天小編就為大家分享一篇關(guān)于JavaScript中的"=、==、==="區(qū)別講解,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2019-01-01
  • javascript實現(xiàn)label標簽跳出循環(huán)操作

    javascript實現(xiàn)label標簽跳出循環(huán)操作

    這篇文章主要為大家詳細介紹了javascript實現(xiàn)label標簽跳出循環(huán)操作,感興趣的朋友可以參考一下
    2016-03-03
  • Javascript中的async awai的用法

    Javascript中的async awai的用法

    本篇文章主要介紹了Javascript中的async/awai的用法,將分享async / await是如何工作的,有興趣的可以了解一下
    2017-05-05
  • js 獲取本地文件及目錄的方法(推薦)

    js 獲取本地文件及目錄的方法(推薦)

    下面小編就為大家?guī)硪黄猨s 獲取本地文件及目錄的方法(推薦)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2016-11-11

最新評論

任丘市| 漳州市| 栾城县| 久治县| 木里| 织金县| 辽宁省| 积石山| 松桃| 浮山县| 通州区| 宜黄县| 乡城县| 宜昌市| 广汉市| 绥阳县| 连山| 繁昌县| 阳朔县| 黄冈市| 南城县| 忻城县| 镇平县| 揭阳市| 阿合奇县| 香河县| 马关县| 泗水县| 建阳市| 桃源县| 迁安市| 通城县| 平陆县| 龙泉市| 铜川市| 临沭县| 军事| 金山区| 格尔木市| 大城县| 枣庄市|