IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 网络协议 -> 六、Express框架 -> 正文阅读

[网络协议]六、Express框架

个人学习笔记,无法保证正确性?


1. Express框架简介

官网
Express是一个基于Node平台的web应用开发框架,它提供了一系列的强大特性,帮助你创建各种Web应用。
可以使用npm install express命令进行下载。

1.) Express特性

  1. 提供了方便简洁的路由定义方式
  2. 对获取HTTP请求参数进行了简化处理
  3. 模板引擎支持程度高,方便渲染动态HTML页面
  4. 提供了中间件机制有效控制HTTP请求
  5. 拥有大量第三方中间件对功能进行扩展



2.) Express语法概括

// 引入Express框架, 实际返回一个方法
const express = require('express');
/*
直接使用框架返回的方法创建web服务器
不需要要引入http模块通过createServer()来创建
*/
const app = express();

/*
通过返回的服务器对象直接调用get(请求地址, 请求处理函数) / post() 来接收客户端的请求
不需要给服务器对象添加请求事件
*/
app.get('/', (req, res) => {
	/*
	通过res.send()来响应客户端,无需在使用res.end()
	send()会自动检测响应内容的类型,并把类型自动设置到响应头当中,也就是说,它自动实现的静态资源的响应。
	同时它也自动设置了响应内容的编码,避免出现乱码
	接着它也自动设置了响应的http状态码
	所以,可以不在使用res.writeHead()来设置响应内容类型以及内容编码
	*/
	res.send('hello, Express!');
	/*
	send()还可以直接给客户端响应一个对象,客户端拿到的是对象的字符串形式, res.end()是没法直接做到的
	res.send({name: 李四, age: 20});
	*/

})

// 监听端口
app.listen(3000);
console.log('网站服务器启动成功');

当我们访问了一个不存在路由,express会自动跳到一个页面给出一个友好提示,比如Cannot GET /list
在这里插入图片描述





2. 中间件

1.) 什么是中间件

中间件就是express框架提供的一堆方法,可以接收客户端发来的请求、可以对请求做出响应;对于一个请求,express框架允许我们设置多个中间件来处理,多个中间件会按照它们被定义的顺序依次来对请求进行处理。
在这里插入图片描述
根据中间件的特殊机制,我们可以用来拦截一些较为复杂且需要处理的请求。



2.) 中间件的组成

中间件主要由两部分构成,中间件方法以及请求处理函数
中间件方法由Express提供,负责拦截请求,请求处理函数由开发人员提供,负责处理请求。

/*
app: express()返回的服务器对象
get()和post就是express提供的中间件方法,内部的处理函数由开发人员自定义
*/
app.get('请求路径', '处理函数') // 接收并处理get请求
app.post('请求路径', '处理函数') // 接收并处理post请求


3.) next()

可以针对同一个请求设置多个中间件,对同一个请求进行多次处理。
但是注意?:默认情况下,请求从上到下依次匹配中间件,一旦匹配成功,终止匹配
可以调用next()将请求的控制权交给下一个中间件,直到遇到结束请求的中间件。

//调用next()之前需要在处理函数中传递 第三个参数next:权限控制函数
app.get('/request', (req, res, next) => {
	req.name = "张三";
	next();
});
app.get('/request', (req, res) => {
	res.send(req.name);
});


4.) app.use() 中间件用法

app.use 匹配所有的请求方式(包括get、post请求),可以直接传入请求处理函数,代表接收所有的请求。

app.use((req, res, next) => {
	console.log(req.url);
	next();
});

app.use 第一个参数也可以传入请求地址,代表不论什么请求方式,只要是这个请求地址就接收这个请求。

app.use('/admin', (req, res, next) => {
	console.log(req.url);
	next();
});


5.) 中间件应用 简单举例

  1. 路由保护,客户端在访问需要登录的页面时,可以先使用中间件判断用户登录状态,用户如果未登录,则拦截请求,直接响应,禁止用户进入需要登录的页面。
  2. 网站维护公告,在所有路由的最上面定义接收所有请求的中间件,直接为客户端做出响应,网站正在维护中。
  3. 自定义404页面
    	app.use((req, res, next) => {
    		/*为客户端响应404状态码以及提示信息
    		通过status()手动设置http状态码, 可链式调用
    		*/
    		res.status(404).send('当前访问的页面是不存在的')
    	})
    


6.) 错误处理中间件

在程序执行的过程中,不可避免的会出现一些无法预料的错误,比如文件读取失败,数据库连接失败。错误处理中间件是一个集中处理错误的地方。

Error()

new Error('错误信息')构造函数用来创建错误对象,通过throw关键字抛出错误对象

err

app.get('/index', (req, res) => {
	//创建错误对象并抛出,程序报错
	throw new Error('程序发生未知错误')
})
//错误处理中间件, 通过传入参数err来接收程序抛出的错误对象
app.use((err, req, res, next) => {
	//err.message: 错误信息
	res.status(500).send(err.message);
})

注意,错误处理中间件 只能捕获同步代码执行出错时throw的错误,无法捕获异步代码执行出错时throw的错误

在node.js中,异步API的错误信息都是通过回调函数获取的,支持Promise对象的异步API发生错误可以通过catch方法捕获。
具体需要手动调用next()方法,并且将错误信息通过参数的形式传递给next()方法,即可触发错误处理中间件。

app.get("/", (req, res, next) => {
	fs.readFile("/file-does-not-exist", (err, data) => {
		if (err) {
			//触发错误中间件
			next(err);
		}
	});
});


7.) 捕获错误

异步函数执行如果发生错误要如何捕获错误呢?
try{}catch(ex){}可以捕获异步函数以及其他同步代码在执行过程中发生的错误,但是不能其他类型的API发生的错误。
错误捕获后通过next()错误信息即可触发错误处理中间件

app.get("/", async (req, res, next) => {
	try {
		await User.find({name: '张三'})
	}catch(ex) {
		next(ex);
	}
});



3. Express框架请求处理

1.) 构建模块化路由

express.Router

// home.js
const express = require('express');
// 通过 express.Router() 创建路由对象
const home = express.Router();
//在home路由下继续创建路由
home.get('/index', () => {
	// home/index
	res.send('欢迎来到博客展示页面');
});
//导出路由对象
module.exports = home;
// admin.js
const express = require('express');
const admin = express.Router();
admin.get('/index', () => {
res.send('欢迎来到博客管理页面');
});
module.exports = admin;
// app.js
const home = require('./route/home.js');
const admin = require('./route/admin.js');

//将路由和请求路径进行匹配
app.use('/home', home);
app.use('/admin', admin);


2.) GET参数的获取

req.query

Express框架中使用req.query即可获取GET参数,框架内部会将GET参数转换为对象并返回。

// 接收地址栏中问号后面的参数
// 例如: http://localhost:3000/?name=zhangsan&age=30
app.get('/', (req, res) => {
console.log(req.query); // {"name": "zhangsan", "age": "30"}
});

Express路由参数

这是一种较为特殊的获取get请求参数的方式

//在路由中中指定请求参数, 写法如下
app.get('/find/:id/:name/:age', (req, res) => {
	console.log(req.params); // {id: 123}
});

那么,在浏览器的get请求url是如下这样的
localhost:3000/find/123/张三/20
如果url没有参数,那么就访问不到 /find 路由



2.) POST参数的获取

body-parser

Express中接收post请求参数需要借助第三方包 body-parser,下载并引用

// 引入body-parser模块
const bodyParser = require('body-parser');
/* 配置body-parser模块
具体过程: 
使用use中间件拦截所有请求,
调用bodyParser.urlencoded()对请求进行处理,并返回一个函数
	方法内部会检测当前请求是否包含请求参数,并接收请求参数
	将请求参数转换为对象类型
	为req请求对象添加属性,属性名: "body",并把请求参数对象赋给body属性
	调用next()将请求控制权交给下一个中间件
 extended参数
 	false: urlencoded()内部会使用querystring系统模块对请求参数的格式进行处理
 	true: urlencoded()内部会使用第三方模块 qs 对请求参数进行处理
*/
app.use(bodyParser.urlencoded({ extended: false }));
// 接收请求
app.post('/add', (req, res) => {
	// 接收请求参数
	console.log(req.body);
})


3.) 静态资源的处理

express.static()

通过Express内置的express.static可以方便地托管静态文件,例如img、CSS、JavaScript 文件等。

/*static()实现逻辑:
判断当前请求是否访问静态资源,
	如果是, 直接把静态资源响应给客户端并终止当前请求。
	如果不是,那么方法内部会调用next()将请求控制权传递给下一个中间件
*/
app.use(express.static('静态资源存放目录绝对路径'));

现在,public 目录下面的文件就可以访问了, 比如:

  • http://localhost:3000/images/kitten.jpg
  • http://localhost:3000/css/style.css
  • http://localhost:3000/js/app.js
  • http://localhost:3000/images/bg.png
  • http://localhost:3000/hello.html

另外还可以指定虚拟路径

// 注意:/static实际上并不存在
app.use('static',express.static('静态资源存放目录绝对路径')

访问时要注意虚拟路劲
http://localhost:3000/static/images/kitten.jpg





4. express-art-template模板引擎

app.engine()

app.set()

res.render()

为了使 art-template 模板引擎能够更好的和 Express 框架配合,模板引擎官方在原 art-template 模板引擎的基础上封装了express-art-template,两者语法上基本一致
使用npm install art-template express-art-template命令进行安装。

//当渲染后缀为art的模板时 使用express-art-template
app.engine('art', require('express-art-template')

/*app.set() : 对express框架进行配置, 通过第一个参数指定当前需要配置什么
	'views': 设置模板存放目录
	'view engine': 设置模板默认后缀
*/
app.set('views', path.join(__dirname, 'views'));
// 渲染模板时不写后缀 默认拼接art后缀
app.set('view engine', 'art');

app.get('/', (req, res) => {
/* res.render(): 渲染模板
方式内部逻辑:
	1. 拼接模板路径
	2. 拼接模板后缀
	3. 哪一个模板和哪一个数据进行拼接
	4. 将拼接结果响应给了客户端
参数
参数1:模板文件名
参数2:渲染数据
*/
	res.render('index',{});
});


app.locals 对象

将变量设置到app.locals对象下面,这个数据在所有的模板中都可以获取到。

app.locals.users = [{
		name: '张三',
		age: 20
	},{
		name: '李四',
		age: 20
}]
<ul>
	{{each users}}
		<li>$value.name</li>
		<li>$value.age</li>
	{{/each}}
</ul>
  网络协议 最新文章
使用Easyswoole 搭建简单的Websoket服务
常见的数据通信方式有哪些?
Openssl 1024bit RSA算法---公私钥获取和处
HTTPS协议的密钥交换流程
《小白WEB安全入门》03. 漏洞篇
HttpRunner4.x 安装与使用
2021-07-04
手写RPC学习笔记
K8S高可用版本部署
mySQL计算IP地址范围
上一篇文章      下一篇文章      查看所有文章
加:2021-09-03 12:18:17  更:2021-09-03 12:19:03 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年12日历 -2024/12/28 21:37:32-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码
数据统计