node.js系列 9 express框架核心用法以及源码
Posted lin_fightin
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了node.js系列 9 express框架核心用法以及源码相关的知识,希望对你有一定的参考价值。
express
express是对http模块的一个封装,是一个相对简单的框架。核心就是中间件!!!!!!!(回调函数)
最基本的使用
以后的开发基本是基于这三个以上的
next的作用是当有两个同样的路劲监听时,加next就会执行第二个,不加就会卡在第一个,不执行第二个。
还可以app.post处理post请求等等。
认识中间件
express的核心就是中间件,express本身功能很少,但可以借助一系列中间件使其功能强大。中间件的本质时传给express的一个回调函数,这个回调函数接受三个参数,req, res, next。
中间件可以做啥事呢? 执行任何代码,更改req, res对象,结束请求-响应周期,可以调用stack(栈中)下一个中间件。
如果在当前的中间件没有结束请求,比如没有res.end,res.send等等,那必须要调用next,否则就会卡在那里,不响应又不往下走。
express主要提供两种方式:
app/router.use 和app/router.methods
methods比如app.get,app.post等等
app.use
methos的本质是use的特殊情况
没有next只会执行第一个。如果有响应和next都存在就报错。
路劲匹配
只匹配路劲,不区分get post。但是普通中间件存在的情况下,还是先匹配普通中间件的。因为普通中间件是匹配所有的
路劲方法一起匹配的中间件
这个也是在普通中间件和路劲中间件后再执行的(如果存在的话)。
连续注册中间件
连续四次注册中间件。
中间件的应用
解析请求体Json对象
但如果是其他的content-type就不能使用这个方法了
body-parser库,专门处理请求体的数据
在expess 4.16版本以上已经内置在了express里面,可以直接使用app.use(express.json())处理json对象
app.use(express.Urlencoded({extended: true}))等等,传入true时,对urlencoded解析时使用qs。传false时,使用node内置的querystring来处理请求体。
分别对应处理json和x-ww的数据。
解析form-data(普通数据)
刚才的express.json和express.urlencoded是无法处理的,所以得借助另一个库multer。
yarn add multer
这样就可以解析form-data的数据了
form-data(图片上传等)
正常的不行
一般上传图片是有对应的接口的。
默认上传的图片是没有后缀名的,
files是文件的信息,我们一般返回
图片的路劲然后开放静态资源就可以在前端直接使用了。
如果加
我们就得通过req.files()来拿,而没加的时候就是req.file,
array时候就是多个文件,也需要通过req.files来拿,single是单个文件,直接通过req.file拿就行了。
还有个警告,官网提示最好不要将any放在全局中间件上,因为any是匹配所有的,而用户可能会恶意上传,
、所以最好是
放在对应的中间件里面去。
保存日志信息
yarn add morgan
这样就能保存信息
响应内容
res.status返回状态码,res.json返回json格式的数据
express的路由
我们的路劲一般都是,比如/users/xxx, /shop/xxx,我们的users/shop一般会分为二级路由
如果Admin就是一个二级路由,看看使用
也就是/api/admin就会走Admin这个二级路由,
二级路由也有自己的子路由,也就是说比如/api/admin/create/:resource这个路劲就会通过/api/admin找到二级路由Admin,再通过/create/:resource找到Admin下的子路由,执行itemCreate这个回调函数。这就是一个二级路由、
当然也有三级路由,四级路由等等,具体看需求需要。
静态资源服务器
node可以作为静态资源服务器,开放后启动服务器,就可以通过localhost:8000/xx/xx来访问到静态资源,比如文件图片等等。
express也已经实现了这个功能,
express.static(路劲),也是使用中间件,表示匹配到/uploads就执行回调函数
这样就开放成功了。
express错误处理
像这种错误处理逻辑就多余了
使用错误处理中间件
错误就next(‘错误信息’),然后使用错误处理中间件就好。这里应该是err就是错误信息,而不用err.message。next(‘’)带参数就是走错误处理中间件。
express源码简单阅读
搞懂四件事
1 调用express()创建的是什么
2 app.listen()启动服务器 express=>http.createServe.Listen
3 app.use(中间件)内部的实现
4 用户发送网络请求时,中间件如何被回调。
5 next为啥会执行下一个中间件
下载一份express源码
第一个问题
拿到返回的app
这个是混入,将proto的混入到app上,比如app.listen的方法就是在这里赋予的,
本质上就是http模块的监听,只不过封装了一层。createServe传入了app,然后apply使得app短暂的拥有了listen的方法。
第三个问题:app.use()
将使用this.lazyyrouter获取router对象
遍历传入的所有中间件
遍历所有的回调函数然后使用router.use()所以app.use本质上就是router.use()(子路由)然后前面说过app.use的回调函数是放在stack栈执行的,
通过f12一层一层招进去
这里创建了stack
router.use本质上也是proto.use,拿到所有的回调函数然后放到stack里面去。
第三个问题解决了。app.use本质上就是调用router.use(),router.use是通过lazyrouter()创建的,然后返回一个Router实例,所有router.use本质也是proto.use,这个方法将所有的回调函数遍历并且放到stack去。
第四个问题 next()
创建express()时,执行了handle
进来又看到,router.handle()
其实本质就是执行这个proto.handle
拿到stack
主动掉next。
会遍历一直找匹配到的中间件。
找到的话调用这个
然后执行fn,fn就是我们注册的中间件,所以就是在这里执行的。
这就是next的执行
第四五个问题解决了。
小结 express()本质上就是一个运行一个函数返回一个app,app.listen本质上就是调用http的createServe.listen而且使用apply。app.use本质上就是调用router.use(),router.use是通过lazyrouter()创建的,然后返回一个Router实例,所有router.use本质也是proto.use,这个方法将所有的回调函数遍历并且放到stack去。第四五个问题就是中间件被执行,一开始创建express的时候就会执行app.handle,然后再下执行router.handle,本质上就是router的proto.handle函数,这个函数会拿到存放回调函数的stack然后主动调用next(),next方法会遍历找到匹配到router然后执行
fn就是找到的回调函数,然后执行。
简单的源码解读,有空会深读。
以上是关于node.js系列 9 express框架核心用法以及源码的主要内容,如果未能解决你的问题,请参考以下文章