Express 入门指南(超详细教程)

一、安装

1. 安装node.js,准备node环境

2. 创建新文件夹,运行 npm init 创建package.json

bash 复制代码
npm init 

3. 安装express

bash 复制代码
npm install express

4. 根目录新建 app.js

js 复制代码
const express = require('express')
const app = express()
const port = 3000

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

app.listen(port, () => {
  console.log(`Example app listening on port ${port}`)
})

5.在package.json的scripts中增加命令

json 复制代码
 "scripts": {
   "dev": "node app.js",
 },

6. 本地运行

bash 复制代码
npm run dev

7. 浏览器中加载 http://localhost:3000/

二、路由

1. 基本路由

js 复制代码
app.get('/', (req, res) => {
  res.send('Hello World!')
})

2. 不同HTTP方法的路由

js 复制代码
app.get('/users', (req, res) => {
  res.json({ message: 'GET: 获取用户列表' })
})

app.post('/users', (req, res) => {
  res.json({ message: 'POST: 创建新用户', data: req.body })
})

app.put('/users/:id', (req, res) => {
  res.json({ message: `PUT: 更新用户ID为 ${req.params.id}`, data: req.body })
})

app.delete('/users/:id', (req, res) => {
  res.json({ message: `DELETE: 删除用户ID为 ${req.params.id}` })
})

3. 动态路由参数

GET请求

js 复制代码
app.get('/users/:id', (req, res) => {
  const userId = req.params.id
  res.json({ message: `获取用户ID为 ${userId} 的信息` })
})
// 示例请求: GET http://localhost:3000/users/123
// 输出: { message: "获取用户ID为 123 的信息" }

POST请求

js 复制代码
app.post('/users/:id', (req, res) => {
  const userId = req.params.id
  const data = req.body //req.body 默认值为 undefined,关于该参数的具体处理方式将在下文详细说明
  res.json({ message: `为用户ID为 ${userId} 创建资源`, data })
})
// 示例请求: POST http://localhost:3000/users/123
// 请求体: { "name": "Tom" }
// 输出: { message: "为用户ID为 123 创建资源", data: { name: "Tom" } }

4. 多个路由参数

js 复制代码
app.get('/users/:userId/posts/:postId', (req, res) => {
  const { userId, postId } = req.params
  res.json({ message: `用户 ${userId} 的帖子 ${postId}` })
})
// 示例请求: GET http://localhost:3000/users/5/posts/42
// 输出: { message: "用户 5 的帖子 42" }

5. 响应方法

方法 描述
res.download() 提示要下载的文件
res.end() 结束响应过程
res.json() 发送 JSON 响应
res.jsonp() 发送带有 JSONP 支持的 JSON 响应
res.redirect() 重定向请求
res.render() 渲染视图模板
res.send() 发送各种类型的响应
res.sendFile() 将文件作为八位字节流发送
res.sendStatus() 设置响应状态码并将其字符串表示形式作为响应正文发送

三、静态文件

要提供静态文件,例如图像、CSS 文件和 JavaScript 文件,请使用 Express 中的 express.static 内置中间件函数。

js 复制代码
express.static(root, [options])

root 参数指定提供静态资产的根目录。有关 options 参数的更多信息,请参阅 express.static

例如,使用以下代码在名为 public 的目录中提供图像:

js 复制代码
app.use(express.static('public'))
//更安全写法
app.use(express.static(path.join(__dirname, 'public')))
//现在,您可以加载 public 目录中的文件:
http://localhost:3000/images/xxxx.png

四、中间件

1. 应用中间件

没有挂载路径的中间件函数。每次应用收到请求时都会执行该函数。

js 复制代码
const express = require("express");
const app = express();

// 对所有请求生效
app.use((req, res, next) => {
  console.log("Time:", Date.now());
  next();
});

挂载在/user/:id路径上的中间件函数。该函数针对 /user/:id 路径上的任何类型的 HTTP 请求执行。

js 复制代码
app.use('/user/:id', (req, res, next) => {
  console.log('Request Type:', req.method)
  next()
})

2. 路由中间件

js 复制代码
const express = require('express')
const app = express()
const router = express.Router()

// 没有挂载路径的中间件功能。对路由器的每个请求都执行此代码
router.use((req, res, next) => {
  console.log('Time:', Date.now())
  next()
})

// 一个中间件子栈显示针对/user/:id路径的任何类型HTTP请求的请求信息
router.use('/user/:id', (req, res, next) => {
  console.log('Request URL:', req.originalUrl)
  next()
}, (req, res, next) => {
  console.log('Request Type:', req.method)
  next()
})

// 在主应用上挂载路由
app.use('/', router)

3. 错误中间件

js 复制代码
//必须接收 4 个参数 (err, req, res, next):
app.use((err, req, res, next) => {
  console.error(err.stack);
  res.status(500).send("Something broke!");
});

4. 内置中间件

  • express.static 提供静态资源,例如 HTML 文件、图像等。
  • express.json 使用 JSON 有效负载解析传入请求。注意:可用于 Express 4.16.0+
  • express.urlencoded 使用 URL 编码的负载解析传入的请求。注意:可用于 Express 4.16.0+

5. 第三方中间件

社区提供的中间件,需额外安装:

  • morgan:HTTP 请求日志。
  • helmet:增强安全性(设置 HTTP 头)。
  • cors:跨域资源共享(CORS)。
  • passport:身份认证。

示例:

js 复制代码
const morgan = require("morgan");
const helmet = require("helmet");

app.use(morgan("dev")); // 日志记录
app.use(helmet()); // 安全防护

五、req.body

Express 默认不会解析 HTTP 请求的 body 数据(如 JSON 或表单数据),因此 req.body 初始值为 undefined。要解析请求体,可以使用内置的 express.json()express.urlencoded() 中间件,或者选择第三方 body-parser 中间件。

js 复制代码
const express = require('express');
const app = express();

// 解析 JSON 格式的请求体(Content-Type: application/json)
app.use(express.json());

// 解析表单数据(Content-Type: application/x-www-form-urlencoded)
app.use(express.urlencoded({ extended: true }));

// 现在 req.body 可以正常获取数据了
app.post('/users/:id', (req, res) => {
  const userId = req.params.id;
  const data = req.body;
  console.log(data); // 这里会打印请求体数据
  res.json({ message: `为用户ID为 ${userId} 创建资源`, data });
});

app.listen(3000, () => {
  console.log('Server is running on http://localhost:3000');
});

注意点

如果是 JSON 数据,确保请求头包含:

js 复制代码
Content-Type: application/json

如果是表单数据,确保请求头包含:

js 复制代码
Content-Type: application/x-www-form-urlencoded

六、跨越处理

1. 使用 cors 中间件

cors 是 Express 最常用的跨域解决方案,支持灵活配置。

2. 安装 cors

bash 复制代码
npm install cors

3. 基本用法(允许所有跨域请求)

js 复制代码
const express = require("express");
const cors = require("cors");
const app = express();

// 允许所有来源的请求
app.use(cors());

app.get("/data", (req, res) => {
  res.json({ message: "跨域请求成功!" });
});

app.listen(3000, () => {
  console.log("Server running on http://localhost:3000");
});

七、文件上传

multer 是 Express 最常用的文件上传中间件,支持单文件、多文件、限制文件类型等功能。

1. 安装 multer

bash 复制代码
npm install multer

2. 基本用法

单文件上传

js 复制代码
const express = require("express");
const multer = require("multer");
const path = require("path");

const app = express();
const upload = multer({ dest: "uploads/" }); // 文件存储目录

// 单文件上传(字段名 "file")
app.post("/upload", upload.single("file"), (req, res) => {
  console.log(req.file); // 上传的文件信息
  res.send("文件上传成功!");
});

app.listen(3000, () => {
  console.log("Server running on http://localhost:3000");
});

前端 HTML 示例:

html 复制代码
<form action="http://localhost:3000/upload" method="post" enctype="multipart/form-data">
  <input type="file" name="file" />
  <button type="submit">上传</button>
</form>

3. 多文件上传

js 复制代码
// 多文件上传(字段名 "files",最多 5 个文件)
app.post("/upload-multiple", upload.array("files", 5), (req, res) => {
  console.log(req.files); // 文件数组
  res.send("多文件上传成功!");
});

4. 自定义存储 & 文件名

js 复制代码
const storage = multer.diskStorage({
  destination: (req, file, cb) => {
    cb(null, "uploads/"); // 存储目录
  },
  filename: (req, file, cb) => {
    // 文件名:时间戳 + 原始后缀
    const ext = path.extname(file.originalname);
    cb(null, Date.now() + ext);
  },
});

const upload = multer({ storage });

5.限制文件类型

js 复制代码
const upload = multer({
  storage,
  fileFilter: (req, file, cb) => {
    const allowedTypes = ["image/jpeg", "image/png"];
    if (!allowedTypes.includes(file.mimetype)) {
      return cb(new Error("仅支持 JPG/PNG 文件"));
    }
    cb(null, true);
  },
  limits: { fileSize: 5 * 1024 * 1024 }, // 限制 5MB
});

6. 错误处理

js 复制代码
// 捕获 multer 错误
app.use((err, req, res, next) => {
  if (err instanceof multer.MulterError) {
    res.status(400).send(`文件上传错误: ${err.message}`);
  } else {
    next(err);
  }
});

八、连接数据库

1. 数据库部分

1.1 新增连接

1.2 新建数据库

1.3 新增user表

1.4 添加一条数据

2. express部分

2.1 安装 mysql2

bash 复制代码
npm install mysql2

2.2 基本连接与查询

js 复制代码
const express = require("express");
const mysql = require("mysql2");
const app = express();

// 创建数据库连接池
const pool = mysql.createPool({
  host: "localhost",     // 数据库地址
  user: "root",         // 用户名
  password: "root",    // 密码
  database: "manage",   // 数据库名
  waitForConnections: true,
  connectionLimit: 10,   // 连接池大小
  queueLimit: 0,
});

// 测试连接
pool.getConnection((err, connection) => {
  if (err) {
    console.error("数据库连接失败:", err.stack);
    return;
  }
  console.log("数据库连接成功,线程ID:", connection.threadId);
  connection.release(); // 释放连接回连接池
});

// 查询示例
app.get("/user", (req, res) => {
  pool.query("SELECT * FROM user", (err, results) => {
    if (err) {
      return res.status(500).json({ error: err.message });
    }
    res.json(results);
  });
});

app.listen(3000, () => {
  console.log("Server running on http://localhost:3000");
});

2.3 查询数据

相关推荐
麦兜*1 小时前
Spring Boot 集成Reactive Web 性能优化全栈技术方案,包含底层原理、压测方法论、参数调优
java·前端·spring boot·spring·spring cloud·性能优化·maven
知了一笑1 小时前
独立开发第二周:构建、执行、规划
java·前端·后端
UI前端开发工作室2 小时前
数字孪生技术为UI前端提供新视角:产品性能的实时模拟与预测
大数据·前端
Sapphire~2 小时前
重学前端004 --- html 表单
前端·html
颖川初尘2 小时前
端口到底是个什么鬼?回答我!
服务器·网络·tcp/ip·node.js
遇到困难睡大觉哈哈2 小时前
CSS中的Element语法
前端·css
Real_man2 小时前
新物种与新法则:AI重塑开发与产品未来
前端·后端·面试
小彭努力中2 小时前
147.在 Vue3 中使用 OpenLayers 地图上 ECharts 模拟飞机循环飞行
前端·javascript·vue.js·ecmascript·echarts
老马聊技术2 小时前
日历插件-FullCalendar的详细使用
前端·javascript
咔咔一顿操作2 小时前
Cesium实战:交互式多边形绘制与编辑功能完全指南(最终修复版)
前端·javascript·3d·vue