当前位置: 首页 > 后端技术 > Node.js

玩转Koa——koa-bodyparser原理解析

时间:2023-04-03 15:01:02 Node.js

1.预备知识在了解koa-bodyparser的原理之前,首先需要了解一些HTTP相关的知识。1、消息体HTTP消息主要分为请求消息和响应消息,而koa-bodyparser主要是处理请求消息。请求消息主要由以下三部分组成:消息头空行消息体koa-bodyparser中的body是指请求消息中的消息体。2、服务端获取报文主体的过程HTTP底层使用TCP提供可靠的字节流服务。简单来说就是报文的主体部分会被转换成二进制数据在网络中传输,所以服务器端首先需要得到二进制流数据。说到网络传输,当然会涉及到传输速度的优化,而优化的手段之一就是对内容进行压缩编码。常用的压缩编码方式有:gzipcompressdeflateidentity(不进行压缩或不改变的默认编码格式)server端会根据消息头信息中的Content-Encoding来确认使用哪种解压编码。接下来需要将二进制数据转换成相应的字符,而字符也有不同的字符编码方式。比如UTF-8和GBK,在汉字处理上有着巨大的差异,UTF-8编码汉字通常需要三个字节,而GBK只需要两个字节。因此,还需要在请求报文的头部信息中设置Content-Type所使用的字符编码信息(默认使用UTF-8),以便服务端使用相应的字符规则进行解码,得到正确的字符串。服务器拿到字符串后,会再次询问:客户端,这个字符串是什么意思?根据不同的应用场景,客户端会对字符串使用不同的编码方式。常见的编码方式有:URL编码方式:a=1&b=2JSON编码方式:{a:1,b:2}客户端会使用字符串编码方式在请求头信息的Content-Type属性中设置消息,让服务端根据相应的字符串编码规则进行解码,就可以理解客户端传输的信息。下面一步一步来分析下koa-bodyparser是如何处理这一系列操作来获取消息体内容的。2.获取二进制数据流NodeJS中获取请求消息体的二进制数据流主要是通过监听请求对象的data事件来完成的://例1consthttp=require('http')http.createServer((req,res)=>{constbody=[]req.on('data',chunk=>{body.push(chunk)})req.on('end',()=>{constchunks=Buffer.concat(body)//接收到的二进制数据流//使用res.endres.end(chunks.toString())})}).listen(1234)koa-bodyparser主要封装了co-body,以及[co-body]主要是利用raw-body模块获取请求消息体的二进制数据流,[row-body]主要是对上述示例代码进行封装和稳健处理。3.内容解码客户端会将内容编码方式放入请求报文头信息的Content-Encoding属性中。服务器收到消息体的二进制数据后,会根据消息头信息进行解压。当然,服务端可以在响应报文头信息的Accept-Encoding属性中添加支持的解压方式。[row-body]主要使用inflation模块进行解压处理。4.字符解码一般来说,UTF-8是互联网上主流的字符编码方式。前面说了,还有GBK的编码方式。相对于UTF-8编码中文只需要2个字节,所以在字符解码中使用UTF-8误解码GBK编码的字符时,会出现中文乱码的问题。NodeJS主要通过Buffer处理二进制数据流,但不支持GBK字符编码,需要通过iconv-lite模块进行处理。[示例1][示例1]中的代码存在没有正确处理字符编码的问题。如果邮件正文中的字符采用GBK编码方式,难免会出现中文乱码:constrequest=require('request')consticonv=require('iconv-lite')request.post({url:'http://localhost:1234/',body:iconv.encode('Chinese','gbk'),headers:{'Content-Type':'text/plain;charset=GBK'}},(error,response,body)=>{console.log(body)//出现中文乱码})NodeJS中的Buffer默认采用UTF-8字符编码处理,这里我们使用【iconv-lite】模块处理不同的字符编码方式:constchunks=Buffer.concat(body)res.end(iconv.decode(chunks,charset))//charset是通过Content-Type得到的5.字符串解码前面说到字符串的两种编码方式,它们对应的Content-类型有:URL编码application/x-www-form-urlencodedJSON编码application/json对于前端来说,URL编码并不陌生,经常用于URL拼接操作,唯一要注意的是不要忘记对键值对进行decodeURIComponent()处理。客户端发送请求体时,需要进行编码操作:'a=1&b=2&c=3'服务端根据URL编码规则对其进行解码,得到对应的对象。//URL编码的简单解码方法实现函数decode(qs,sep='&',eq='='){constobj={}qs=qs.split(sep)for(leti=0,max=qs.length;i