手机版

深入分析koa-bodyparser原理

时间:2021-08-27 来源:互联网 编辑:宝哥软件园 浏览:

一、预先了解

在理解koa-bodyparser的原理之前,我们需要了解一些关于HTTP的知识。

1.消息正文

HTTP消息主要分为请求消息和响应消息,koa-bodyparser主要处理请求消息。

请求消息主要由以下三部分组成:

消息头将消息正文留空,而koa-bodyparser中的正文引用请求消息中的消息正文。

2.服务器获取消息体流

HTTP底层使用TCP提供可靠的字节流服务。简单来说,消息体会被转换成二进制数据在网络中传输,所以服务器需要先获取二进制流数据。

说到网络传输,肯定会涉及到传输速度的优化,优化方法之一就是对内容进行压缩编码。常用的压缩和编码方法有:

Gzip compress deflate identity(不执行压缩或不会更改的默认编码格式)。服务器端将根据消息头信息中的内容编码确认采用何种解压缩编码。

然后,二进制数据需要转换成相应的字符,字符有不同的字符编码方式。比如汉字处理差异较大的UTF-8和GBK,通常需要三个字节来编码汉字,而GBK只需要两个字节。因此,有必要在请求消息的报头信息中设置Content-Type所使用的字符编码信息(默认采用UTF-8),以便服务器可以使用相应的字符规则来解码并获得正确的字符串。

得到字符串后,服务器会再次问:客户端,这个字符串是什么意思?

根据不同的应用场景,客户端会对字符串采用不同的编码方式。常见的编码方法包括:

URL编码方式: a=1b=2 JSON编码方式: {a:1,b:2}客户端会在请求消息头信息的Content-Type属性中设置采用的字符串编码方式,以便服务器根据对应的字符串编码规则进行解码,了解客户端传输的信息。

下面对koa-bodyparser的分步分析就是如何处理这一系列操作,从而得到消息体内容。

2、获取二进制数据流

在NodeJS中获取请求消息体的二进制数据流主要通过监控请求对象的数据事件来完成:

//示例1 const http=require(' http ')http . createserver((req,RES)={const body=[] req.on ('data ',chunk={ body . push(chunk)})req . on(' end ',()={const chunks=buffer。concat(body)//接收到二进制数据流//用res.end (chunks)响应。tostring ())})})。listen (1234)而koa-bodyparser主要封装co-body,【co-body】主要使用raw-body模块获取请求消息体的二进制数据流,【row-body】主要封装并健壮处理上述示例代码。

第三,内容解码

客户端将把内容编码方法放入请求消息头信息的内容编码属性中。当服务器收到消息体的二进制数据时,会根据头信息进行解压缩。当然,服务器可以将支持的解压缩方法添加到响应消息头信息的Accept-Encoding属性中。

而【行体】主要使用充气模块解压。

4.字符解码

总的来说,UTF 8是互联网上主流的字符编码方式。如前所述,还有GBK编码法。与UTF-8相比,它只需要2个字节来编码中文。如果在字符解码中误用UTF-8来解码GBK编码的字符,就会出现汉字乱码的问题。

NodeJS主要通过Buffer处理二进制数据流,但不支持GBK字符编码,需要通过iconv-lite模块进行处理。

存在示例1中的代码没有正确处理字符编码的问题,因此消息体中的字符采用GBK编码方式,这必然会导致中文乱码字符:

const request=require(' request ')const iconv=require(' iconv-lite ')请求。post({ URL : ' http://localhost :1234/',body: iconv.encode('中文,' gbk '),报头RS : { '内容类型' : '纯文本/纯文本;charset=GBK' }},(错误,响应,正文)={ console.log(正文)//发生中文乱码情况})NodeJS中的缓冲器默认是采用UTF-8字符编码处理,这里借助【iconv-lite】模块处理不同的字符编码方式:

const chunks=缓冲区。concat(body)RES . end(iconv。解码(组块,字符集))//字符集通过内容类型得到五、字符串解码

前面已经提到了字符串的二种编码方式,它们对应的内容类型分别为:

统一资源定位器编码应用程序/x-www-form-URL编码JSON编码应用程序/json对于前端来说,网址编码并不陌生,经常会用于统一资源定位器拼接操作,唯一需要注意的是不要忘记对键值对进行decodeURIComponent()处理。

当客户端发送请求主体时,需要进行编码操作:

a=1b=2c=3 '服务器端再根据统一资源定位器编码规则解码,得到相应的对象。

//网址编码方式简单的解码方法实现函数decode (qs,sep=' ',eq='='){ const obj={ } QS=QS。(让i=0,max=qs.length我最大;I){ const item=QS[I]const index=item。indexof(eq)let key,value if(~ index){ key=item。substr(0,索引)值=item。substr(索引1)} else { key=item value=' ' } key=decodeURIComponent(key)value=decodeURIComponent(value)if(!物体。hasown属性(键)){ obj[key]=value } }返回obj }控制台。日志(解码(' a=1b=2c=3 ')/{ a : ' 1 ',b: '2 ',c: '3' }URL编码方式适合处理简单的键值对数据,并且很多框架的埃阿斯中的内容类型默认值都是它,但是对于复杂的嵌套对象就不太好处理了,这时就需要数据编码方式大显身手了。

客户端发送请求主体时,只需要采用JSON.stringify进行编码。服务器端只需要采用JSON.parse进行解码即可:

const strijsonreg=/^[\x20\x09\x0a\x0d]*(\[|\{)/;函数解析(str) { if(!严格)返回字符串?JSON。解析(字符串):字符串;//严格模式下,总是返回一个对象if(!字符串)返回{ };//是否为合法的数据字符串if(!strijsonreg。测试(str)){ 0抛出新的错误('无效的JSON,只支持对象和数组');}返回JSON。解析(字符串);}除了上述两种字符串编码方式koa-bodyparser还支持不采用任何字符串编码方式的普通字符串。

三种字符串编码的处理方式由【共体】模块提供koa-bodyparser中通过判断当前内容类型类型,调用不同的处理方式,将获取到的结果挂载在ctx.request.body:

返回异步函数bodyParser(ctx,next) { if (ctx.request.body!==未定义)返回等待下一个();if (ctx.disableBodyParser)返回等待下一个();尝试{ //最重要的一步将解析的内容挂载到寇阿相思树的上下文中const RES=等待ParseBody(CTX);' ctx.request.body='解析'在res?已解析的RES . { };如果(CTX。请求。生身===未定义)CTX。请求。生体=RES . raw//保存原始字符串} catch(err){ if(one rror){ one rror(err,CTX);} else { throw err } } wait next();};异步非同步(asynchronous)函数parseBody(CTX){ if(enableJson)((detectJSON detectJSON(CTX))| | CTX。请求。is(JSON类型)){ return await parse。联署材料1(CTX,联署材料1);//应用程序/json等JSON类型} if(启用FORm CTX。请求。is(FORm TYPes)){返回等待解析。FORm(CTX,FORm opts);//application/x-www-form-URL编码} if(启用文本CTX。请求。is(文本类型)){ return await parse。文本(CTX,文本选项)| | ';//文本/纯文本}返回{ };}};其实还有一种比较常见的内容类型,当采用表单上传时,报文主体中会包含多个实体主体:

-webkitformboundryqsagb6us 6f 7s 3 fcontent-disposition :表单-数据;名称=' imagefilename=' image . png ' content-type : image/png-webkitformboundryqsagmb6 us6 f7s 3 fcontent-disposition :表单-数据;name=' text '-webkitformboundryqsagb6us 6f 7s 3sf-这个方法比较复杂,koa-bodyparser中没有提供Content-Type解析。(_应在下一篇文章中介绍)

动词(verb的缩写)摘要

以上就是koa-bodyparser的核心实现原理,其中涉及了很多关于HTTP的基础知识。对于不熟悉HTTP的同学,可以推荐看一波入门书籍【HTTP图解】。

最后,留下一张图片:

以上就是本文的全部内容。希望对大家的学习有帮助,支持我们。

版权声明:深入分析koa-bodyparser原理是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。