1.项目开始
实际工作其实是都需要使用框架/工具的,可以让我们更加关注业务逻辑(封装了一些基本的 API 什么的),且有一定的流程和标准(中间件机制)来开发插件/工具(拆开,低耦合) 什么的来形成一个解决方案.
使用express:
- express是Nodejs最为常用的web server框架;
- 什么是框架?
- 不要以为express过时了
- 目录:
- express下载、安装和使用,express中间件机制
- 开发接口,连接数据库,实现登录,日志记录
- 分析express中间件原理
2.express安装
框架基本上都是使用脚手架来生成简单的代码;
介绍express:
- 安装过程(使用脚手架express-generator)
- 初始化代码介绍,处理路由;
- 使用中间件;
安装express:
- npm install express-generator -g
- express express-test
- npm install & npm start
在最外面安装 express-generator-g(全局安装),然后 express blog-express 生成 blog-express 项目,进入目录下 npm install 运行 npm start 就可以访问了,打开 bin 文件夹里面有一个 www.js 有说明默认端口是多少! 为了方便重启和环境区分,依然需要按照 nodemon 和 cross-env。
所以 www.js 就是提供和执行一个 APP 的服务,具体服务(回调函数)在 app.js 书写。加一个 dev 命令。 简单看一下目录,bin 里面有一个提供执行 app.js 服务的 www.js, public 是存放静态目录(同样的是 web server 不必关心的),route 存放的是路由, view 存放的是 html 模板(由
于做 web server 故不必关心)。 至于为什么会有这两个用不到的文件夹,主要是框架提供的 是一个全栈项目,而我们只是关注后端(忽略 views 和 public 就行。
3.介绍express的入口代码
介绍app.js
- 各个插件的作用
- 思考各个插件的实现原理(结合之前学过的知识)
- 处理get请求和post请求
首先是 createError 这个就是针对一些路由错误,传入一个指定错误的数字如 404 返回一个比较友好的提示(并不重要)。 express 和 path 没什么好说的,当然是需要引入。 cookieParser 就是用来解析 cookie 的,就不用自己写,注册就行了。处理后我们在路由那里就可以使用 req.cookies 访问 cookie 了,类似于我们之前做的,只不过考虑到更多的意外情况什么的,这个已经被封装成插件我们直接使用就行。
logger/morgan 就是处理日志的,我们之前要自己实现 access函数还需要定义日志内容,这里直接使用就行,当然,需要一些配置。 原理上这些插件和我们自己写的是差不多的,主要是更完善
一些。
接下来就是引入路由,初始化 express 为 app ,也就是本次系统运行后就可以监听客户端访问,每次客户端访问/http 请求都会形成一个实例.至于 set 可以不关心,主要是注册视图引擎(前端页面, views 部分),由于主要后端可以不管。 接下来就是 use ,就是使用各个插件,什么是 express.json ? 类似我们的 postData 用来获取 post 数据且放在 req.body ,而 一旦使用这个插件我们就可以直接在路由中使用req.body 直接访问 post 数据(当然这个只是局限 content-type 是 json 的情况)。 什么是 express.urlencoded ?这个也是和上面差不多,只不过 是监听 content-type 为 x-www-form-urlencoded ,一般是上传的 key vlaue 那种表单提交的数据,也就是说兼容处理不是json 的格式。目的都是往 req.body 塞 post 的数据。 然后是处理 cookie 的,而什么 static 也可以忽略,主要是处理静态文件的,注释就行。
接下来是注册路由,这里直接 router.get ,括号内加一个路径远比我们直接 if 判断简洁,且其是回调函数而不是直接一群if。那么为什么注册的时候还需要加路径?其实应该看注册时的路径才对(示例都是/ ,直到注册的时候才有区分,之前注释的应该取消,不然页面有用到,出不来)也就是说注册的时候是父路径,写的时候是子路径(父路径如/user ,子路径是/abc 则访问 /user/abc 才能到这个页面!)! error handler 主要是处理程序出现的问题,抛出问题,不过 这里 env 要与我们环境变量那里设置的一致才行(里面不是 dev 即不是开发环境就不把 bug 抛来而是返回一个空,说明上线的话有 bug 不应该把自己的错误抛给外网的用户)。
4.演示express怎么处理路由
我们直接新建 blog.js 和 user.js 作为我们自己的路由。 blog 这里直接写一个 /list 的路由,返回一个 json 就行,回到 app.js 引用 blog ,注册路由。再写个 detail ,好处是我们只需 要关注最底层的路由,顶层的父路由已经写完了,这个分离 就比较合适修改,只需要修改父路由即可,拆分更加明确。 至于返回 json 格式,我们之前需要 req.end 返回一个 json 化 的字符串,不能直接返回 json ,不过由于 express 帮我们封 装了一些,所以可以很轻松的使用 res.json 返回一个 json 格 式的数据,自动帮我们转换,甚至帮我们加了个返回格式的 头(content-type)。至于每次定义一个路由有一个 next !这个中间件会提到。
接下来是 user.js ,这个的 post 数据可以直接从 req.body 拿到。下节的中间件就可以解释什么是 use 和 next 了。
const blogRouter = require('./routes/blog'); comst userPouter = require('./routes/user'0; app.use('/api/blog',blogRouter); app.use('/api/user',userRouter);
5.express中间件
中间件机制:
- 有很多app.use
- 代码中的next参数是什么?
- 带着这一些一问,我们先看一段代码;
首先建一个 express-test 文件夹,npm 初始化一些,入口文件改成 app.js,建一个 app.js,安装 express。 注意 use 可以传入一个路由然后处理函数,也可以直接就传 入一个函数。
引入 express ,建一个 express 示例(称为 app )。第一个 use打印一段话然后 next (),第二个 use 设置一个 cookie 然后 next(),第三个 use 设置一个定时器随便出来东西然后 next (),第四个 use 传入一个路由,随便打印一个内容然后 next ()。最后一模一样的改 use 为 get ,再加一个一模一样的改为 post 。
先解释三个路由, use 是不管什么请求(get/post 乱七八糟的请求都可以走这个),get 是 get 请求, post 是 post 请求。 (注意如此使用与前面用 router 也是一样的) 再加一个 get 请求其它路由随便打印东西,返回点内容,这 次不要 next (),再加个 post 请求其它路由随便打印东西也
返回点东西,不要 next ()。最后 use 统一处理 404 ,返回一个 404 的信息。最后 app.listen 监听一下才能跑起来。 Ok,再注意一下,不过走哪个路由其实都会触发那些直接写函数的 use (没写路由就是会命中,都会走这个 use ,要是写明路由,不一样自然不会命中不会走)。走完这一个发现有 nex ( t )就会去找同样的 get/post 请求(取决于有路由的函数是什么请求)和普通的 use (不带 get 和 post,当然有路由的话只要是包含就行,如请求的是 /api/a ,那么有个/api 的路由也是可以)。从上到下执行app.use 直接注册的函数和 app.use 直接注册而且前面有路由(该路由符合父路由)的函数。分为 get 请求和 post 请求和随便瞎编的 get 请求(前面无 api 和前面有 api )四种情况。
那么什么是中间件,就是上面这么多函数,里面的内容就是中间件(当然参数需要有那三个 req 、 res 、 next )即 app.use 里面的内容,可以通过 next ()向下一步步合理的串联。 还有另外的写法,就是 app.use/get/post 可以插入多个中间 件/ 函数(当然前面的中间件记得 next )!当然了多函数的话,其实最好是最后一个函数是专门处理的主函数,前面的函数作为验证函数,也不要太多(3 以内)就足够了。