1.概述
Express是一个基于Node平台的web应用开发框架,它提供了一系列强大的特性,帮助创建各种web应用。
下载方式:npm install express
2.特性
- 提供了方便简洁的路由定义方式
- 对获取http请求参数进行了简化处理
- 对模板引擎支持成都高,方便渲染动态html页面
- 提供了中间件机制有效控制http请求
- 拥有大量第三方中间件对功能进行扩展
3.express框架入门
//引入express框架
const express = require('express');
//创建服务器
const app = express();
app.get('/', (req, res) => {
//send()
//1.send方法内部会自动检测响应内容的类型
//2.send方法内部会自动设置http状态码
//3.send方法会帮助我们自动设置相应内容类型和编码
res.send('hello.express');
});
app.get('/list',(req,res)=>{
res.send({name:'张三',age:20});
});
app.listen(3000);
console.log('网站服务器启动成功')
4.中间件
4.1 get.post中间件
中间件就是一堆方法,可以接收客户端发来的请求,可以对请求做出响应,也可以将请求继续交给下一个中间件继续处理
可以针对同一个请求设置多个中间件,对同一个请求进行多次处理。
默认情况下,请求从上到下一次匹配中间件,一旦匹配成功终止匹配。
可以调用next方法将请求的控制权交给下一个中间件,知道遇到结束请求的中间件。
//引入express框架
const express = require('express');
//创建服务器
const app = express();
app.get('/request', (req, res, next) => {
req.name = '张三';
next();
});
app.get('/request', (req, res) => {
res.send(req.name);
});
app.listen(3000);
console.log('网站服务器启动成功')
4.2 app.user中间件
app.use 匹配所有的请求方式,可以直接传入请求处理函数,代表接收所有的请求
//引入express框架
const express = require('express');
//创建服务器
const app = express();
//接受所有请求
app.use((req, res, next) => {
console.log('请求走了app.use中间件');
next();
});
//当访问request 接受请求
app.use('/request',(req, res, next) => {
console.log('请求走了app.use/request中间件');
next();
});
app.use('/list',(req,res,next)=>{
res.send('list');
})
app.get('/request', (req, res, next) => {
req.name = '张三';
next();
});
app.get('/request', (req, res) => {
res.send(req.name);
});
app.listen(3000);
console.log('网站服务器启动成功')
4.3 中间间应用
- 路由保护,登录拦截跳转
- 网站维护公告
- 自定义404页面
//引入express框架
const express = require('express');
//创建服务器
const app = express();
//网站公告
// app.use((req, res, next) => {
// res.send('网站正在维护');
// });
//网站登录
app.use('/admin', (req, res, next) => {
let isLogin = true;
if (isLogin) {
next();
} else {
res.send('你还没有登录,不能访问admin这个页面');
}
});
app.get('/admin', (req, res) => {
res.status(200).send('你已经登录,可以访问当前页面');
});
//当前客户端相应404
app.use((req,res,next)=>{
res.status(404).send('当前访问的页面是不存在的');
});
app.listen(3000);
console.log('网站服务器启动成功')//引入express框架
const express = require('express');
//创建服务器
const app = express();
//网站公告
// app.use((req, res, next) => {
// res.send('网站正在维护');
// });
//网站登录
app.use('/admin', (req, res, next) => {
let isLogin = true;
if (isLogin) {
next();
} else {
res.send('你还没有登录,不能访问admin这个页面');
}
});
app.get('/admin', (req, res) => {
res.status(200).send('你已经登录,可以访问当前页面');
});
//当前客户端相应404
app.use((req,res,next)=>{
res.status(404).send('当前访问的页面是不存在的');
});
app.listen(3000);
console.log('网站服务器启动成功')
4.4错误处理中间件
在程序执行的过程中,不可避免的会出现一些无法预料的错误,比如文件读取失败,数据库连接失败,错误处理中间件是一个集中处理错我的地方
当程序出现场错误后,在调用next方法,并将错误信息通过参数传递给next()方法,即可触发错误处理中间件
//引入express框架
const express = require('express');
const fs = require('fs');
//创建服务器
const app = express();
app.get('/index', (req, res, next) => {
// throw new Error('服务器发生未知错误');
fs.readFile('./文件清单.txt', 'utf8', (err, result) => {
if (err != null) {
next(err);
} else {
res.send(result);
}
});
// res.send('程序正常执行');
});
//错误处理中间件四个参数
app.use((err, req, res, next) => {
res.status(500).send(err.message);
});
app.listen(3000);
console.log('网站服务器启动成功')
4.5 捕获错误
在node.js中,异步api的错误信息都是通过回调函数获取的,支持Promise对象的异步api发生错误可通过catch方法捕获,异步函数执行如果发生错误要如何捕获错误呢?
tyr catch可以捕获异步函数几其同步代码在执行过程中发生的错误,但是不能捕获其他类型的api发生从错误
//引入express框架
const express = require('express');
const fs = require('fs');
const promisify = require('util').promisify;
const readFile = promisify(fs.readFile);
//创建服务器
const app = express();
app.get('/index', async (req, res, next) => {
try {
await readFile('./aaa.js')
} catch (e) {
next(e);
}
});
//错误处理中间件四个参数
app.use((err, req, res, next) => {
res.status(500).send(err.message);
});
app.listen(3000);
console.log('网站服务器启动成功')
5.Express请求处理
5.1构建模块化路由
app.js
const express = require('express');
const app = express();
//创建路由对象
const home = express.Router();
//为路由对象匹配请求对象
app.use('/home', home);
//创建二级路由
home.get('/index', (req, res) => {
res.send('欢迎来到博客首页');
});
app.listen(3000);
home.js
const express = require('express');
const home = express.Router();
home.get('/index', (req, res) => {
res.send('欢迎来到首页');
});
module.exports = home;
index.js
const express = require('express');
const admin = express.Router();
admin.get('/index', (req, res) => {
res.send('欢迎来到管理页面');
});
module.exports = admin;
5.2 GET参数的获取
Express框架中使用req.query即可获取GET参数,框架内部会将GET参数转换为对象并返回。
const express = require('express');
const app = express();
app.get('/index', (req, res) => {
//获取请求参数 ?name=ithedan&age=30
res.send(req.query);//{'name':'ithedan','age':''30}
});
app.listen(3000);
5.3 POST参数的获取
Express中接受post请求参数需要借助第三方包 body-parser
const express = require('express');
const app = express();
//获取post 请求参数 需要用到三方模块body-parser
const bodyParser = require('body-parser');
//配置body-parser模板
//extended:false 方法内部使用queyrstring模块处理参数的格式
//extended:true 方法内部使用第三方模块qs处理请求参数的格式
app.use(bodyParser.urlencoded({extended: false}));
app.post('/add', (req, res) => {
res.send(req.body);
});
app.listen(3000);
5.4 Express路由参数
const express = require('express');
const app = express();
app.get('/index/:id/:name/:age', (req, res) => {
res.send(req.params);
//{"id": "21", "name": "ithedan", "age": "32" }
});
app.listen(3000);
localhost:3000/index/21/ithedan/32
5.5 静态资源的处理
通过Express内置的express.static可以方便地托管静态文件,例如img css JavaScript文件等
const express = require('express');
const app = express();
const path = require('path');
//实现静态资源访问功能 static虚拟路径 localhost:3000/static/----
// app.use('/static',express.static(path.join(__dirname, 'public')));
app.use(express.static(path.join(__dirname, 'public')));
app.listen(3000);
http://localhost:3000/css/style.css
6 express-art template 模板引擎
- 为了是art-template模板引擎能够更好的和express框架配合,模板引擎官方在元art-template模板引擎的基础上封装了express-art-template
- 使用 npm install art-template express-art-template
const express = require('express');
const app = express();
const path = require('path');
//当渲染后缀为art的模板时,使用express-art-template
app.engine('art', require('express-art-template'));
//设置模板目录
app.set('views', path.join(__dirname, 'views'));
//设置默认后缀
app.set('view engine', 'art');
//模板中可以获取到
app.locals.users = [{
name: '张三',
age: 18
}, {
name: '李四',
age: 18
}, {
name: '王五',
age: 18
},]
app.get('/index', (req, res) => {
//1 拼接模板路径
//2 拼接模板后缀
//3 哪一个模板和哪一个数据进行拼接
//4 将拼接结果反馈给客户端
res.render('index', {
msg: 'message'
});
});
app.get('/list', (req, res) => {
res.render('list', {
msg: 'list page'
})
});
app.listen(3000);
7。 项目案例初始化
7.1. 建立项目所需文件夹
public 静态资源
model 数据库操作
route 路由
views 模板
7.2. 初始化项目描述文件
npm init -y
7.3. 下载项目所需第三方模块
npm install express mongoose art-template express-art-template
7.4. 创建网站服务器
//引入express模块创建服务器
const express = require('express');
const app = express();
//引入路由模块
const home = require('./route/home');
const admin = require('./route/admin');
//引入express-session
const session = require('express-session');
//引入数据库
require('./model/connect');
//引入path模块用了操作路径
const path = require('path');
//引入body-parser 用来处理post请求参数
const bodyParser = require('body-parser');
//引入art-template
const template = require('art-template');
//引入dateformat模块用来处理日期
const dateFormat = require('dateformat');
//配置session
app.use(session({
secret: 'cookie_secret',
resave: true,
saveUninitialized: true
}));
//告诉express 框架模板所在的位置
app.set('views', path.join(__dirname, 'views'));
//告诉express 模板默认后缀
app.set('view engine', 'art');
//当渲染后缀为art的模板时,所使用的模板引擎是什么
app.engine('art', require('express-art-template'));
//开放静态资源文件
app.use(express.static(path.join(__dirname, 'public')));
//处理post请求参数
app.use(bodyParser.urlencoded({extended: false}));
//登录拦截
app.use('/admin', require('./middleware/loginGuard'));
//关联路由模块 为路由匹配路径
app.use('/home', home);
app.use('/admin', admin);
//错误处理中间件
app.use((err, req, res, next) => {
console.log(err.message)
//将字符串对象转换为对象类型
const result = JSON.parse(err);
const params = [];
for (let attr in result) {
if (attr != 'path') {
params.push(attr + "=" + result[attr]);
}
}
return res.redirect(`${result.path}?${params.join('&')}`);
});
//向模板内部导入dateFormat变量
template.defaults.imports.dateFormat = dateFormat;
//app监听默认端口80
app.listen(80);
console.log('网站服务器启动成功,通过访问localhost来访问');