Express.js

简介

Express.js 简介

Express.js 是一个基于 Node.js 的 Web 应用框架,提供了一系列强大而灵活的特性,用于构建单页、多页和混合 Web 应用。它简化了服务器端代码的编写,极大地提高了开发效率。

核心特性

  1. 简洁性:Express.js 提供了一个极简的核心框架,开发者可以根据需要进行扩展和定制。
  2. 中间件机制:使用中间件处理请求,可以实现模块化和可重用的代码。
  3. 路由系统:提供强大的路由定义方式,支持动态路由和参数。
  4. 视图系统:支持多种模板引擎,如 Pug(以前称为 Jade)、EJS 等,方便生成动态 HTML。
  5. HTTP 实用功能:提供一系列 HTTP 工具,用于处理请求、响应、Cookies、文件上传等。

安装

要使用 Express.js,首先需要安装 Node.js 和 npm(Node Package Manager)。然后,可以通过以下命令安装 Express.js:

npm install express

基本示例

以下是一个简单的 Express.js 应用示例,展示了如何创建一个基本的 Web 服务器:

// 引入 Express 模块
const express = require('express');

// 创建一个 Express 应用
const app = express();

// 定义根路由的处理器
app.get('/', (req, res) => {
  res.send('Hello, World!');
});

// 启动服务器并监听指定端口
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
  console.log(`Server is running on port ${PORT}`);
});

中间件

中间件函数是 Express.js 的核心概念,用于处理请求和响应。在请求处理过程中,中间件函数按顺序执行。中间件可以执行以下任务: - 执行任何代码 - 修改请求对象和响应对象 - 结束请求-响应循环 - 调用下一个中间件函数

示例:

// 应用级中间件
app.use((req, res, next) => {
  console.log('Time:', Date.now());
  next();
});

路由

Express.js 提供了强大的路由功能,可以轻松定义各种 HTTP 方法的路由。路由定义包括路径和处理函数。

// 定义一个 GET 路由
app.get('/user/:id', (req, res) => {
  res.send(`User ID: ${req.params.id}`);
});

// 定义一个 POST 路由
app.post('/user', (req, res) => {
  res.send('Got a POST request');
});

使用模板引擎

Express.js 支持多种模板引擎,用于生成动态 HTML 内容。以下示例使用 Pug 模板引擎:

app.set('view engine', 'pug');

app.get('/hello', (req, res) => {
  res.render('index', { title: 'Hey', message: 'Hello there!' });
});

错误处理

Express.js 提供了简单的错误处理机制,通过定义错误处理中间件来捕获和处理错误:

app.use((err, req, res, next) => {
  console.error(err.stack);
  res.status(500).send('Something broke!');
});

静态文件

Express.js 可以方便地提供静态文件(如图像、CSS 文件和 JavaScript 文件):

app.use(express.static('public'));

总结

Express.js 是一个极简、高效、灵活的 Web 应用框架,适合构建各种规模的 Web 应用。从简单的静态网站到复杂的 RESTful API,Express.js 提供了丰富的功能和良好的扩展性,是 Node.js 开发者不可或缺的工具。

常用方法

下面是一些常用的 Express.js 代码片段,涵盖了路由处理、中间件使用、模板引擎、错误处理和静态文件服务等常见任务。

1. 基本服务器设置

const express = require('express');
const app = express();
const PORT = process.env.PORT || 3000;

app.listen(PORT, () => {
  console.log(`Server is running on port ${PORT}`);
});

2. 路由处理

GET 请求

app.get('/', (req, res) => {
  res.send('Hello, World!');
});

app.get('/user/:id', (req, res) => {
  res.send(`User ID: ${req.params.id}`);
});

POST 请求

app.post('/user', (req, res) => {
  res.send('Got a POST request');
});

3. 使用中间件

应用级中间件

app.use((req, res, next) => {
  console.log('Time:', Date.now());
  next();
});

app.use('/user/:id', (req, res, next) => {
  console.log('Request Type:', req.method);
  next();
});

路由级中间件

const userRouter = express.Router();

userRouter.use((req, res, next) => {
  console.log('Request URL:', req.originalUrl);
  next();
});

userRouter.get('/:id', (req, res) => {
  res.send(`User ID: ${req.params.id}`);
});

app.use('/user', userRouter);

4. 处理 JSON 和 URL 编码的数据

app.use(express.json());
app.use(express.urlencoded({ extended: true }));

app.post('/login', (req, res) => {
  res.send(`Username: ${req.body.username}, Password: ${req.body.password}`);
});

5. 使用模板引擎

app.set('view engine', 'pug');
app.set('views', './views');

app.get('/hello', (req, res) => {
  res.render('index', { title: 'Hey', message: 'Hello there!' });
});

6. 静态文件服务

app.use(express.static('public'));

7. 错误处理

app.use((err, req, res, next) => {
  console.error(err.stack);
  res.status(500).send('Something broke!');
});

8. 处理 404 错误

app.use((req, res, next) => {
  res.status(404).send("Sorry can't find that!");
});

9. 设置 HTTP 头

app.use((req, res, next) => {
  res.setHeader('Content-Type', 'application/json');
  next();
});

10. 路由参数和查询字符串

app.get('/search', (req, res) => {
  res.send(`Query: ${req.query.q}`);
});

app.get('/user/:id', (req, res) => {
  res.send(`User ID: ${req.params.id}`);
});

11. 重定向和发送文件

app.get('/redirect', (req, res) => {
  res.redirect('https://example.com');
});

app.get('/download', (req, res) => {
  res.download('/path/to/file', 'filename.ext');
});

12. 集成第三方中间件

const morgan = require('morgan');
app.use(morgan('combined'));

const helmet = require('helmet');
app.use(helmet());

这些代码片段涵盖了 Express.js 开发中常见的场景,可以帮助你快速构建和维护 Web 应用程序。根据项目的需求,可以灵活组合和扩展这些代码片段。

简单的例子

下面是一个完整的 Express.js “Hello, World!” 示例,展示了如何设置一个简单的 Web 服务器并处理基本的 GET 请求。

1. 安装 Node.js 和 Express.js

首先,确保你已经安装了 Node.js 和 npm(Node Package Manager)。然后,通过 npm 安装 Express.js:

npm install express

2. 创建项目目录和文件

在你的项目目录中创建一个新的文件 app.js

3. 编写 app.js

app.js 文件中编写以下代码:

// 引入 Express 模块
const express = require('express');

// 创建一个 Express 应用
const app = express();

// 定义根路由的处理器
app.get('/', (req, res) => {
  res.send('Hello, World!');
});

// 启动服务器并监听指定端口
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
  console.log(`Server is running on port ${PORT}`);
});

4. 运行应用

在终端中运行以下命令启动服务器:

node app.js

5. 访问应用

在浏览器中访问 http://localhost:3000,你应该会看到 “Hello, World!” 的输出。

完整代码

以下是完整的 app.js 文件内容:

// 引入 Express 模块
const express = require('express');

// 创建一个 Express 应用
const app = express();

// 定义根路由的处理器
app.get('/', (req, res) => {
  res.send('Hello, World!');
});

// 启动服务器并监听指定端口
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
  console.log(`Server is running on port ${PORT}`);
});

解释

  1. 引入 Express 模块:使用 require('express') 引入 Express 模块。
  2. 创建 Express 应用:调用 express() 函数创建一个 Express 应用实例。
  3. 定义根路由的处理器:使用 app.get() 方法定义一个处理 GET 请求的路由。当用户访问根路径 / 时,服务器将响应 “Hello, World!”。
  4. 启动服务器并监听端口:使用 app.listen() 方法启动服务器,并监听指定的端口(默认为 3000)。

通过上述步骤,你可以创建并运行一个简单的 Express.js “Hello, World!” 应用。这是 Express.js 开发的基础,从这里你可以进一步扩展应用功能。

常用基本概念

在学习和使用 Express.js 时,有几个基本概念是非常重要的。理解这些概念将帮助你更好地掌握和利用 Express.js 来构建 Web 应用程序。

1. 中间件 (Middleware)

中间件函数是 Express.js 的核心概念。中间件是指那些位于请求与响应处理之间的函数,可以对请求对象、响应对象进行操作,或者终止请求-响应循环。中间件有以下几种类型: - 应用级中间件:绑定到应用实例 app 上。 - 路由级中间件:绑定到 express.Router 实例上。 - 错误处理中间件:有四个参数 (err, req, res, next)。 - 内置中间件:例如 express.static。 - 第三方中间件:例如 body-parser

2. 路由 (Routing)

路由定义了应用如何响应客户端对特定终端点的请求。一个路由由一个路径和一个或多个处理函数组成。Express 提供了多种路由方法(如 app.getapp.postapp.putapp.delete)和路由参数(如 req.params)。

3. 请求对象 (Request Object)

请求对象 req 包含了客户端请求的相关信息。常用的属性和方法包括: - req.query: 查询字符串参数。 - req.params: 路由参数。 - req.body: 请求体(需要中间件 express.json()express.urlencoded())。 - req.method: HTTP 方法。 - req.url: 请求的完整 URL。

4. 响应对象 (Response Object)

响应对象 res 用于向客户端发送响应。常用的属性和方法包括: - res.send(): 发送响应。 - res.json(): 发送 JSON 响应。 - res.status(): 设置 HTTP 状态码。 - res.redirect(): 重定向请求。 - res.render(): 渲染视图模板。

5. 应用程序对象 (Application Object)

Express 应用程序对象 app 是你创建的 Express 实例,通常通过调用 express() 函数创建。它用于定义中间件、路由和配置选项。

6. 路由器对象 (Router Object)

路由器对象 express.Router 提供了一种模块化的方式来定义路由和中间件。你可以创建多个路由器实例,并将它们挂载到应用程序对象上。

7. 模板引擎 (Template Engine)

Express 支持多种模板引擎,用于生成动态 HTML。常见的模板引擎有 Pug、EJS、Handlebars 等。你可以通过 app.set('view engine', 'pug') 等方式配置模板引擎。

8. 静态文件服务 (Static Files)

Express 提供了内置的中间件 express.static 来服务静态文件(如图像、CSS 文件和 JavaScript 文件)。你可以通过 app.use(express.static('public')) 配置静态文件目录。

9. 错误处理 (Error Handling)

错误处理中间件有四个参数 (err, req, res, next)。你可以定义错误处理中间件来捕获和处理应用中的错误:

app.use((err, req, res, next) => {
  console.error(err.stack);
  res.status(500).send('Something broke!');
});

10. 环境变量 (Environment Variables)

Express 应用通常使用环境变量来配置不同环境下的行为。你可以使用 process.env 访问环境变量,并通过 dotenv 模块加载 .env 文件中的变量:

require('dotenv').config();
const PORT = process.env.PORT || 3000;

11. 安全性 (Security)

为了提高 Express 应用的安全性,通常会使用中间件如 helmet 来设置 HTTP 头,防止常见的安全漏洞:

const helmet = require('helmet');
app.use(helmet());

这些基本概念是 Express.js 开发的基础,理解并掌握它们将帮助你更好地构建和维护 Web 应用程序。