3、进阶篇 —— Express框架
3.1、Express 框架介绍
安装:npm i express
Express是一个流行的Node.js Web应用程序框架,它提供了一组强大的特性,可以帮助你快速搭建和扩展Web应用程序。以下是Express框架的一些主要特点和概念
① 简洁而灵活的路由系统:Express提供了简洁而灵活的路由定义方式,可以根据HTTP请求的不同方法(GET、POST等)和URL路径(路由)来执行相应的处理逻辑
② 中间件(Middleware):中间件是Express的核心概念之一。它是一个函数,可以访问请求对象(req)、响应对象(res)和应用程序中的下一个中间件函数(next)。中间件函数可以用于执行各种任务,如日志记录、身份验证、请求处理等
③ 模板引擎支持:Express允许你使用各种模板引擎来生成动态HTML页面,如Pug(以前称为Jade)、EJS等
④ 静态文件服务:Express可以轻松地托管静态文件,如HTML、CSS、JavaScript、图像等。这对于构建单页应用程序(SPA)或简单的网站非常有用
⑤ 错误处理:Express提供了一种简单但灵活的错误处理机制,可以捕获和处理应用程序中的错误
⑥ 会话管理:虽然Express本身不提供会话管理功能,但可以轻松集成第三方中间件来实现会话管理,如express-session
⑦ 可扩展性:Express是一个非常灵活的框架,你可以使用第三方中间件和插件来扩展其功能,满足特定需求
⑧ RESTful API支持:由于Express的路由系统非常灵活,因此它非常适合构建RESTful API
总的来说,Express是一个轻量级、快速和灵活的Web应用程序框架,非常适合构建各种类型的Web应用程序,从简单的静态网站到复杂的API服务
3.2、Express 框架初体验
<!-- 前端代码 -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<a href="http://localhost:3000/"><button>点我一下</button></a>
</body>
</html>
// 服务器代码
//引入
const express = require("express");
//创建应用对象
const app = express();
//创建路由
app.get("/", (req, res) => {
res.end("Hello World!");
});
//监听端口启动服务
app.listen(3000, () => {
console.log("服务器已启动,端口3000监听中...");
});
3.3、使用
express实例(app)常用api | 描述 |
---|---|
app.get(path, callback) | 用于处理HTTP GET请求,并且当请求的路径匹配指定的路径时执行回调函数 |
app.post(path, callback) | 用于处理HTTP POST请求 |
app.put(path, callback) | 用于处理HTTP PUT请求 |
app.delete(path, callback) | 用于处理HTTP DELETE请求 |
app.all(path, callback) | 用于处理所有HTTP方法的请求,不论是GET、POST、PUT还是DELETE |
app.use(middleware) | 用于将中间件函数添加到应用程序的请求处理链中。这个中间件函数可以是自定义的,也可以是Express内置的中间件函数 |
app.param(name, callback) | 用于定义路由参数的中间件函数。当某个路由中包含定义的参数时,这个中间件函数将被调用 |
app.get(setting) | 用于获取应用程序的配置参数 |
app.set(setting, value) | 用于设置应用程序的配置参数,如视图引擎、端口号等 |
app.locals | 一个对象,用于存储应用程序的本地变量。这些变量在整个应用程序中都可以访问 |
app.listen(port, [callback]) | 用于启动Express应用程序并监听指定的端口。当应用程序启动时,可选的回调函数将被调用 |
app.route(path) | 用于创建一个新的路由对象,该对象允许在同一路径上定义多个路由处理器 |
app.use(express.static(directory)) | 用于托管静态文件,将指定目录下的文件提供给客户端访问 |
app.engine(ext, callback) | 用于注册模板引擎 |
获取请求报文参数 | 描述 |
---|---|
req.params | 路由中的命名参数,如果有的话 |
req.query | 路由中的查询字符串参数 |
req.body | 请求体中的数据(通常用于POST请求) |
req.headers | 请求头 |
req.cookies | 请求中的cookie |
req.path | 请求的路径 |
req.hostname | 请求的主机名 |
req.ip | 客户端的IP地址 |
req.protocol | 请求的协议(http或https) |
req.method | 请求的HTTP方法(GET、POST等) |
req.url | 请求的完整URL路径 |
req.route | 当前匹配的路由的信息 |
req.xhr | 一个布尔值,指示请求是否是由Ajax发起的 |
req.get(headerName) | 获取特定请求头的值 |
req.httpVersion | 获取http协议的版本号 |
响应设置 | 描述 |
---|---|
兼容 http 模块的的部分 |
|
res.statusCode=xxx | 设置状态码 |
res.statusMessage=‘xxx’ | 设置状态信息 |
res.setHeader(‘xxx’,‘yyy’) | 设置响应头 |
res.write(‘xxx’) | 设置响应体 |
res.end(‘xxx’) | 设置响应体且结束响应 |
express自己的响应方法 |
支持链式调用 |
res.status(xxx) | 设置状态码 |
res.set(‘xxx’,‘yyy’) | 设置响应头 |
res.send(‘xxx’) | 设置响应体 |
其他响应 |
|
res.redirect(‘xxx’) | 重定向 |
res.download(‘xxx’) | 下载响应 |
res.json({…}) | 响应json |
res.sendFile(‘xxx’) | 响应文件内容 |
3.4、中间件
中间件(Middleware)是Express框架中的一个核心概念,它是一个函数,可以访问请求对象(req)、响应对象(res)和应用程序中的下一个中间件函数(next)。中间件函数可以执行各种任务,如处理请求数据、添加响应数据、记录日志、进行身份验证等,其作用最主要是封装公共操作,简化代码
中间件的主要特性 | 描述 |
---|---|
处理请求和响应对象 | 中间件可以对请求和响应进行修改和处理。它们可以读取请求中的数据(如参数、查询字符串、主体内容等),并可以向响应对象中添加数据(如响应头、响应主体等) |
结束请求-响应循环 | 中间件可以通过发送响应结束请求-响应循环。例如,可以使用res.send()、res.json()等方法发送响应并结束请求处理 |
调用下一个中间件 | 中间件可以调用下一个中间件函数,以便将控制权交给下一个中间件。通常使用next()函数来实现。如果中间件不调用next(),则请求将不会继续传递给下一个中间件或路由处理器 |
实现链式处理 | 多个中间件可以串联在一起,以链式方式处理请求。每个中间件都可以对请求进行处理或修改,然后将其传递给下一个中间件 |
常见的中间件类型 | 描述 |
---|---|
应用级中间件 | 绑定到应用实例app,处理应用程序级别的逻辑 |
路由级中间件 | 绑定到特定路由,可以处理特定路由的逻辑 |
错误处理中间件 | 专门用于处理错误的中间件。错误处理中间件有四个参数:err, req, res, next |
内置中间件 | Express提供的一些内置中间件,如express.static用于托管静态文件,express.json和express.urlencoded用于解析请求体 |
第三方中间件 | 可以使用第三方库提供的中间件,如body-parser、cookie-parser、morgan等 |
// 应用级中间件
app.use((req, res, next) => {
console.log('Request URL:', req.originalUrl);
next();
});
// 路由级中间件
app.get('/user/:id', (req, res, next) => {
console.log('Request Type:', req.method);
next();
});
// 错误处理中间件
app.use((err, req, res, next) => {
console.error(err.stack);
res.status(500).send('Something broke!');
});
// 内置中间件
app.use(express.static('public'));
app.use(express.json());
app.use(express.urlencoded({
extended: true }));
// 第三方中间件
const bodyParser = require('body-parser');
app.use(bodyParser.json());
3.5、托管静态文件
express.static是Express框架中用于托管静态文件的中间件。静态文件包括HTML文件、CSS文件、JavaScript文件、图像等。使用express.static中间件,可以让这些文件直接通过URL路径进行访问,而无需编写特定的路由处理器
路由 | 描述 |
---|---|
/ | 匹配静态资源目录下的index.html和路径为 / 的路由 |
/xxx | 匹配静态资源目录下的xxx文件和路径为xxx的路由 |
响应的结果是谁先匹配(写在前面)谁就响应,例如下面的代码,托管静态资源的中间件写在路径为 / 的路由之前,因此当我们访问 / 的时候会优先匹配静态资源目录下的index.html
const express = require("express");
const path = require("path");
const app = express();
// 指定静态文件目录
app.use(express.static(path.join(__dirname, "public")));
app.get("/", (req, res) => {
res.send("Hello World!");
});
// 启动服务器
app.listen(3000, () => {
console.log("Server is running on port 3000");
});
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<a href="http://localhost:3000/info.html"><button>点我一下</button></a>
</body>
</html>
<!-- public/info.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<h1>abc</h1>
</body>
</html>
3.6、获取表单数据
body-parser是一个Node.js中间件,用于解析请求体的内容,并使其可用于Express框架的路由处理器中。在处理HTTP POST请求或PUT请求时,客户端通常会发送数据作为请求体,这些数据可能是JSON、URL编码的参数或者是文本数据。body-parser中间件帮助Express应用程序解析这些请求体,使得在路由处理器中可以方便地访问这些数据
<!-- public/index.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<form action="/login" method="post">
username:<input type="text" name="username"><br>
password:<input type="text" name="password"><br>
<button type="submit">提交</button>
</form>
</body>
</html>
// 服务器代码
const express = require("express");
const app = express();
const path = require("path");
const bodyParser = require("body-parser");
// 指定静态文件目录 中间件在这里作为应用级中间件
app.use(express.static(path.join