Express 是一个基于 Node.js 平台,快速、开放、极简的 web 开发框架。
原生的 http 模块在某些方面表现不足以应对我们的开发需求,所以我们就需要使用框架来加快我们的开发效率,框架的目的就是提高效率,让我们的代码更统一。
- 丰富的 API 支持,强大而灵活的中间件特性
- Express 不对 Node.js 已有的特性进行二次抽象,只是在它之上扩展了 Web 应用所需的基本功能
- 内部使用还是 http 模块
- 有很多流行框架基于 Express
安装
npm install --save express
使用
express 提供一些函数
- app.listen ```javascript const http = require(‘http’);
const express = require(‘express’);
const app = express(); // 返回一个 requestListener 处理器
app.listen(3000); // 相当于 // const server = hhtp.createServer(app); // server.listen(3000);
<a name="KJEZC"></a># 中间件通过中间件对整个处理请求函数增加对应的方法,即把不同对应处理的函数分配到各个中间件中。<br /><a name="CqQOs"></a>## 中间件工作原理app.use([path,] callback [, callback...])中间件的回调函数- 一般响应回调为三个以下或以下- function(req, res)- function(req, res, next)- 错误处理为四个参数 function(err, req, res, next)err 为错误信息<br />req 请求对象,继承自 http.IncomingMessage<br />res 响应对象,继承自 http.ServerResponse- res.send express 的响应函数 res 参数除了可以原生使用 write 等 http 原生写响应,也可以使用 send 方法简化响应体- res.redirect express 提供用于重定向```javascriptres.redirect('/');// 相当于res.statusCode = 302;res.setHeader('Location', '/');
- res.sendFile 返回响应文件
res.status() 指定发送状态码
// 如 404 页面app.use((req, res, next) => {res.status(404).send('<h1>页面走丢了!</h1>');});
next
next() 往后匹配下一个中间件
- next(‘route’) 往后匹配当前中间件堆栈中的下一个
next(x) x为任何除字符串
'route'外,会视当前请求错误,将路过所有剩余无错误处理路由和中间件函数app.use 使用中间件处理各种请求
app.post
- app.get
- app.delete
这些都是一个内置的中间件
这些要完全匹配path
app.use((req, res, next) => {console.log('在中间件中');next(); // 往下流});
多个中间件函数
app.get('/', (req, res, next) => {}, (req, res, next) => {});
中间件堆栈
const cb1 = (req, res, next) => {};const cb2 = (req, res, next) => {};app.get('/', [cb1, cb2]);
中间件链式
app.get('/', (req, res) => {res.send(`get`)}).post('/', (req, res) => {res.send(`post`)}).put('/', (req, res) => {res.send(`put`)}).delete('/', (req, res) => {res.send(`delete`)})
中间件 path 过滤响应与参数
使用 path 控制响应的内容,支持 字符串或正则,可以使用 :params 设置参数
app.get('/', (req, res, next) => { // 在没有匹配到的默认响应console.log('这个中间件永远都会执行');next();});app.get('/add-product', (req, res, next) => { // 在 path 为 '/' 之前增加res.send('<h1>添加产品页面</h1>');});app.get('/', (req, res, next) => { // 在没有匹配到的默认响应res.send('<h1>你好,Express!</h1>');});app.get('/:id', (req, res, next) => {console.log(req.params.id);});// path 字符串// 可以用 ? + {} 等正则量词app.get('/a(bc)?d', (req, res, next) => {});app.get('/ab+', (req, res, next) => {});app.get('/a{1,4}', (req, res, next) => {});// 可以使用 . - 来分隔参数app.get('/:id1.:id2', (req, res, next) => {console.log(req.params.id1);console.log(req.params.id2);});// 可以使用 . - 来分隔参数app.get('/:id1-:id2', (req, res, next) => {console.log(req.params.id1);console.log(req.params.id2);});// 可以使用 . - 来分隔参数app.get('/:id1-:id2', (req, res, next) => {console.log(req.params.id1);console.log(req.params.id2);});// 可以用 (正则) 为参数指定类型,注意字符串要用 \ 转意app.get('/:id1(\\d+), (req, res, next) => {console.log(req.params.id1);console.log(req.params.id2);});// 使用正则匹配app.get(/a/) , (req, res, next) => {});app.get(/^bad.*fly$/) , (req, res, next) => {});
内置中间件
express.json()
express.urlencoded()
app.use(express.json()); // 处理请求体 raw 为 json 的参数app.use(express.urlencoded()); // 处理请求体 x-www-form-urlencoded 的参数app.get('/', function(req, res, next) {console.log(req.body);})
外置中间件
body-parser
用于解析body请求体的解析器
npm install --save body-parser
bodyParser.urlencoded() 返回一个中间件函数
const bodyParser = require('body-parser');app.use(bodyParaser.urlencoded({extended:false})); // 不去处理非标准的请求
:::info express v4 版本其实已经对 body-parser 相关的封装到 express 内置中间件,所以现在也很少使用 body-parser :::
cookie-parser 解析 cookie 数据
cors 跨域
compression 压缩 HTTP 响应
morgan 请求日志
…
其他中间件可以访问:
路由
使用express.Router() 可以分拆业务逻辑, 返回中间件函数
admin.js
const express = require('express');const router = express.Router();router.get('/add-product', (req, res, next) => {res.send('<form action="/product" method="POST"><input type="text" name="message" /><button="submit">发送</button></form>');});router.post('/product', (req,res, next) => {res.redirect('/');});module.exporets = router;
在app.js中, 路径过滤
const adminRoutes = require('./routes/admin');// 在path中加入'/admin'进行路径过滤,即访问时要/admin/add-product才能访问到app.use('/admin', adminRoutes);
静态文件提供
express.static()
app.use(express.static('./public'));
模板引擎


npm install --save ejs pug express-handlebars
配置模板引擎
app.set('view engine', 'pug'); // 配置要使用的引擎app.set('view', './view'); // 配置模板位置
使用模板
route.get('/', (req, res, next) => {res.render('模板文件名', {data:'住模板注入数据'});}
ejs
pug
handlebars
const expressHbs = require('express-handles');app.engine('handlebars', expressHbs({layoutDir: 'views/layouts', defaultLayout: 'main-layout', extname: 'hbs'})); // 要先注册一个模板引擎
