(Turn) Fun Koa - koa-bodyparser analytical principle

Address: http://www.imooc.com/article/274059

First, pre-knowledge

  Before understanding the koa-bodyparser principle, we first need to understand the part of the HTTP-related knowledge.

1, the message body

  HTTP packets are divided into the request packet and response packet, koa-bodyparser main processing for the request packets.

  Request packet consists of the following three components:

  • Packet header
  • Blank line
  • The message body

  Koa-bodyparser in the body refers to the body portion of the request packet in the packet.

2, the server side gets the message body processes

  HTTP uses the underlying TCP provides reliable byte stream service, simply, is the message body portion is converted into binary data transmission in the network, the server first needs to get the binary data stream.

  Turning network transmission, of course, will involve optimization of transmission speed, but one way is to optimize the content compression encoding, the compression encoding methods are used:

  • gzip
  • compress
  • deflate
  • identity (no compression or perform the default encoding format will not change)

  Server will confirm what decompression Content-Encoding The encoder uses packet header information.

  Next, it is necessary to convert the binary data into the corresponding characters, and the characters have different character encoding, for example, Chinese character processing huge difference GBK and UTF-8, UTF-8 character encoding typically requires three bytes, GBK only requires two bytes. Therefore, also you need to set the character code information used in Content-Type (the default is used in the case where the UTF-8) in the header of the information request message, so that the server can use the corresponding character decoding rules to obtain the correct character string.

  After a string to get the server side have to ask: Client, you are a string What do you mean ah?

  Depending on the application scenario, the client will have different string encoding, common coding methods are:

  • URL encoding: a = 1 & b = 2
  • JSON encoding: {a: 1, b: 2}

  Encoding the string of the client will be provided using the Content-Type Attribute Request packet header information, so that the server according to a corresponding decoding string code rules, the client can understand the information passed up.

  Here's how, step by step analysis koa-bodyparser deal with the series of operations, resulting in the message body content.

Second, obtaining a binary data stream

  NodeJS acquiring request message body binary data stream mainly by listening to the request object's data event is completed:

// example a 
const HTTP = the require ( ' HTTP ' ) 

http.createServer ((REQ, RES) => {
   const body = [] 

  req.on ( ' Data ' , the chunk => { 
    body.push (the chunk) 
  }) 
  
  req.on ( ' End ' , () => {
     const of chunks are Buffer.concat = (body) // received binary data stream 

    // use res.end responds process 
    res.end (chunks.toString ()) 
  } ) 
}). the listen ( 1234 )

And koa-bodyparser mainly for co-body of the package, and [co-body] is mainly employed raw-body module acquires binary data stream request message body, [row-body] primarily the encapsulation of the above sample code and robust process.

Third, the content decoding

  Client sends the encoded content into the request packet mode Content-Encoding header attribute information, the server receives a binary data packet body, and will be decompressed operation according to the header information, of course, the server may respond Add the packet header decompression support information Accept-Encoding property.

  [Row-body and - mainly inflation module decompression process.

Fourth, the character encoding

  Generally, UTF-8 is the mainstream of Internet character encoding, there are also mentioned earlier the GBK encoding, compared to UTF-8, which encodes Chinese requires only 2 bytes, then when misused character encoding UTF -8 decoding GBK character encoding, there will be problems Chinese garbled.

  NodeJS mainly deal with binary data stream through the Buffer, but it does not support GBK character encoding is required by iconv-lite processing module.

  [Example] a code there is no problem properly handle character encoding, then the message body using GBK character encoding, bound Chinese garbled:

const request = require('request')
const iconv = require('iconv-lite')

request.post({
  url: 'http://localhost:1234/',
  body: iconv.encode('中文', 'gbk'),
  headers: {
    'Content-Type': 'text/plain;charset=GBK'
  }
}, (error, response, body) => {
  console.log(body) // 发生中文乱码情况
})
The default NodeJS Buffer using UTF-8 character encoding process, where by modules] [iconv-lite different character encoding process:

 const chunks = Buffer.concat(body)
    res.end(iconv.decode(chunks, charset)) // charset通过Content-Type得到

V. string decoding

  As already mentioned two kinds of encoding strings, their corresponding respectively Content-Type:

  • URL encoding application / x-www-form-urlencoded
  • JSON encoding application / json

  For front-end is, is no stranger URL encoding, often the URL for the splicing operation, only caveat is not to forget key-value pairs decodeURIComponent () processing.

  When a client sends a request body, it requires coding operations:

  'a=1&b=2&c=3'
The server then decoded URL encoding rules, to give the corresponding object.
// simple URL encoding implemented method of decoding 
function decode (QS, On Sep = ' & ' , EQ = ' = ' ) {
   const obj = {} 
  QS = qs.split (On Sep) 

  for (the let I = 0 , max = qs.length; I <max; I ++ ) {
     const Item = QS [I]
     const index = item.indexOf (EQ) 

    the let Key, value 

    IF (~ index) { 
      Key = item.substr ( 0 , index) 
      value = Item .substr (+ index . 1 ) 
    }else {
      key = item
      value = ''
    }
    
    key = decodeURIComponent(key)
    value = decodeURIComponent(value)

    if (!obj.hasOwnProperty(key)) {
      obj[key] = value
    }
  }
  return obj
}

console.log(decode('a=1&b=2&c=3')) // { a: '1', b: '2', c: '3' }

 URL encoding for data processing simple key-value pairs, and Content-Type defaults are many Ajax frameworks are in it, but for complex nested objects is not very good deal, then you need to show their talents JSON encoding a.

  When the client sends a request body, we need only be encoded JSON.stringify. JSON.parse server only need to be decoded:

const strictJSONReg = / ^ [\ X20 \ x09 \ x0a \ x0d] * (\ [| \ {) / ; 
function the parse (str) { 
  IF (! strict) return ? str JSON.parse (str): str;
   // in strict mode, always return an object 
  iF (STR!) return {};
   // is a legal JSON string 
  iF (! strictJSONReg.test (STR)) {
     the throw  new new Error ( ' invalid JSON, and only the Supports Object Array ' ); 
  } 
  return the JSON.parse (STR); 
}

 In addition to the above two encoding string, koa-bodyparser also supports normal string string without using any coding method.

  The strings by encoding processing mode] [co-body module, koa-bodyparser current is determined by the type of Content-Type, call different approach, the acquired results mount ctx.request.body:

 return  the async function bodyParser (ctx, the Next) {
     IF (! ctx.request.body == undefined) return  the await the Next ();
     IF (ctx.disableBodyParser) return  the await the Next ();
     the try {
       // most important step will be resolved koa mounted to the contents of the context 
      const RES = the await parseBody (CTX); 
      ctx.request.body = ' of Parsed '  in RES? res.parsed: {};
       IF (ctx.request.rawBody === undefined) CTX = res.raw .request.rawBody; // save the original string 
    } the catch (err) {
      if (onerror) {
        onerror(err, ctx);
      } else {
        throw err;
      }
    }
    await next();
  };

  async function parseBody(ctx) {
    if (enableJson && ((detectJSON && detectJSON(ctx)) || ctx.request.is(jsonTypes))) {
      return await parse.json(ctx, jsonOpts); // application/json等json type
    }
    if (enableForm && ctx.request.is(formTypes)) {
      return await parse.form(ctx, formOpts); // application/x-www-form-urlencoded
    }
    if (enableText && ctx.request.is(textTypes)) {
      return await parse.text(ctx, textOpts) || ''; // text/plain
    }
    return {};
  }
};
In fact, there is a relatively common Content-type, when using form upload, message body contains multiple entities subject:
------WebKitFormBoundaryqsAGMB6Us6F7s3SF
Content-Disposition: form-data; name="image"; filename="image.png"
Content-Type: image/png


------WebKitFormBoundaryqsAGMB6Us6F7s3SF
Content-Disposition: form-data; name="text"

------WebKitFormBoundaryqsAGMB6Us6F7s3SF--

  This process is relatively complex manner, koa-bodyparser and do not provide the Content-Type of the parse. (Next should be introduced _)

V. Summary

  The above is the core koa-bodyparser implementation principle, which involves a lot of the basics of HTTP, for HTTP not familiar with the students, can recommend to see a wave of entry-level graphic book [HTTP].

 

Author: descire
link: http: //www.imooc.com/article/274059
Source: Mu class network
article published in the original Mu-class network, please indicate the source, thank you

Guess you like

Origin www.cnblogs.com/zhaobao1830/p/11202649.html