ai全栈-node.js相关的学习之路(草稿版)

一、安装node

nodejs官网:Node.js --- Run JavaScript Everywhere

安装完成后查看nodejs版本判断时候安装成功

javascript 复制代码
node -v

二、创建node项目

1、首先新建一个文件夹,名字任起,如wx-server,然后就可以初始化node项目及安装所需的一些工具了。

javascript 复制代码
//初始化 Node 项目
npm init -y
//装后端需要的工具
npm i express axios cors body-parser

三、nodejs的基本操作

1、nodejs运行指定文件

javascript 复制代码
//node 文件名 (需含后缀,并且这不会触发热更新)
例:node index.js
//若想触发热更新需安装nodemon插件
安装命令:
npm i nodemon -g
此时就可使用nodemon 命令运行指定文件
例:nodemon index.js

四、如何使用nodejs搭建服务器

方式一:使用 Node.js 原生 HTTP(最基础 ✅)

1️⃣ 创建 server.js

javascript 复制代码
//引入 Node.js 内置的 http模块
const http = require('http')
//创建一个 HTTP 服务器,其中 req 与 res 是请求对象和响应对象
const server = http.createServer((req, res) => {
//设置状态码 200,并返回响应头
res.writeHead(200, { 'Content-Type': 'text/plain; charset=utf-8' })
//返回数据并结束响应
res.end('你好,Node.js')
})
const PORT = 3000
//监听 3000 端口
server.listen(PORT, () => {
console.log(服务器启动成功:http://localhost:${PORT})
})

2️⃣ 启动服务器

javascript 复制代码
nodemon server.js

浏览器访问:

javascript 复制代码
http://localhost:3000

详细示例:

javascript 复制代码
// 第一步:引入 Node.js 内置模块
// http 模块:用来创建服务器(必须)
const http = require('http')
// url 模块:用来解析浏览器地址栏里的 URL
const url = require('url')
// querystring 模块:用来解析 POST 表单数据
const querystring = require('querystring')
// 第二步:创建 HTTP 服务器
//http.createServer() 用来创建一个服务器,其中req是请求参数、res是响应参数
const server = http.createServer((req, res) => {
// 第三步:解析请求信息
/*
req.url 是浏览器访问的路径
例如:http://localhost:3000/getinfo?id=1
使用 url.parse() 解析后:
pathname = '/getinfo'
query    = { id: '1' }
*/
const parsedUrl = url.parse(req.url, true)
const pathname = parsedUrl.pathname // 请求路径
const query = parsedUrl.query       // GET 请求参数
const method = req.method           // 请求方式(GET 或 POST)
// 第四步:设置响应头(防止中文乱码)
/*
告诉浏览器:
1. 返回的是普通文本
2. 使用 UTF-8 编码(否则中文会乱码)
*/
res.setHeader('Content-Type', 'text/plain;charset=utf-8')
// 第五步:路由判断(重点!)
/*
路由 = 根据不同的 URL 和请求方式,做不同的事情
*/
// ① 处理 GET 请求
if (method === 'GET' && pathname === '/getinfo') {
console.log('GET 参数:', query)
// 返回响应给浏览器
res.end('GET 请求成功')
return
}
// ② 处理 POST 请求
if (method === 'POST' && pathname === '/postinfo') {
let postData = ''
/*
POST 数据是"分段"传过来的
我们需要监听两个事件:
1. data  :收到数据
2. end   :数据接收完成
*/
// 每次收到一小段数据
req.on('data', chunk => {
postData += chunk.toString()
})
// 所有数据接收完成
req.on('end', () => {
  /*
    把字符串转换成对象
    例如:username=admin&password=123
    转换后:{ username: 'admin', password: '123' }
  */
  const body = querystring.parse(postData)
  console.log('POST 参数:', body)
  // 返回 JSON 数据
  res.setHeader('Content-Type', 'application/json;charset=utf-8')
  res.end(JSON.stringify({
    code: 200,
    msg: 'POST 成功',
    data: body
  }))
})

return
}
// 第六步:404 处理(接口不存在)
res.statusCode = 404
res.end('404 Not Found')
})
// 第七步:启动服务器
/*
服务器必须监听一个端口
端口就像"门牌号"
*/
const PORT = 3000
server.listen(PORT, () => {
console.log('服务器启动:http://localhost:3000')
})

疑问解答:

1、http模块是干嘛的?

http模块是 Node.js 用来创建 Web 服务器的核心模块。

有了它,你才可以:创建服务器、监听端口、接收 HTTP 请求、返回响应

✅ 没有 http模块,Node.js 本身不能当服务器用。

2、res.writeHead()中的第二个参数是什么?Content-Type是什么?

第二个参数是响应头。告诉客户端:返回的数据是什么类型,text/plain指纯文本。text/html指html页面。application/json指JSON数据。image/png指图片。

javascript 复制代码
res.writeHead(200, { 'Content-Type': 'text/plain; charset=utf-8' })

3、如果不写 writeHead会怎样?

Node.js 会:默认状态码:200、默认 Content-Type: text/plain、默但中文很容易会乱码。

方式二:使用 Express(✅ 企业级推荐)

1️⃣ 安装 Express

javascript 复制代码
npm install express

2️⃣ 创建 app.js

javascript 复制代码
//引入 Express 框架
const express = require('express')
//创建一个 Express 应用实例
const app = express()
// 中间件(解析 JSON),即让服务器能够自动解析前端发送的 JSON 数据
app.use(express.json())
// 路由(这里的意思是当用户访问根路径 /时,执行对应的处理函数并返回数据)
app.get('/', (req, res) => {
res.send('你好 Express!')
})
// 创建GET 接口
app.get('/api/user', (req, res) => {
res.json({
code: 200,
data: { name: '张三', age: 18 }
})
})
// 创建POST 接口
app.post('/api/login', (req, res) => {
const { username } = req.body
res.json({
code: 200,
msg: 欢迎回来,${username}
})
})
//启动服务器并监听指定的端口(3000),等待客户端来连接
const PORT = 3000
app.listen(PORT, () => {
console.log(Express 服务器启动:http://localhost:${PORT})
})

3️⃣ 启动

javascript 复制代码
nodemon app.js

测试接口:

javascript 复制代码
curl http://localhost:3000/api/user

疑问解答:

1、express是干什么用的?

Express 是基于 Node.js 的 Web 应用框架,它的核心作用是:帮你更简单、更高效地搭建服务器和处理 HTTP 请求。

2、为什么要用 Express?(对比原生 Node.js)

1️⃣ 原生 Node.js(麻烦)

javascript 复制代码
const http = require('http')
http.createServer((req, res) => {
if (req.url === '/user' && req.method === 'GET') {
res.writeHead(200, { 'Content-Type': 'application/json' })
res.end(JSON.stringify({ name: '张三' }))
}
}).listen(3000)

❌ 问题:

  • 要自己判断 url

  • 要自己判断 method

  • 代码臃肿,不好维护

2️⃣ 使用 Express(简单 ✅)

javascript 复制代码
const express = require('express')
const app = express()
app.get('/user', (req, res) => {
res.json({ name: '张三' })
})
app.listen(3000)

✅ 优点:

  • 路由清晰

  • 自动解析 JSON

  • 代码少一半以上

3、Express 主要干什么用?

功能 说明
路由 处理 /login/user/order等接口
中间件 统一处理日志、鉴权、错误处理
请求解析 自动解析 JSON、表单数据
接口返回 一行 res.json()搞定
生态丰富 有 cors、jwt、multer 等插件

4、Express 最核心的三个概念

1️⃣ 路由(Route)

javascript 复制代码
app.get('/', handler)
app.post('/login', handler)
app.put('/user/:id', handler)

根据 URL + 请求方式​ 处理不同逻辑

2️⃣ 中间件(Middleware)✅ 最重要

javascript 复制代码
app.use((req, res, next) => {
  console.log('有人访问了服务器')
  next()
})

中间件 = 请求到达接口前的"关卡"

常见用途:

  • 登录校验

  • 权限判断

  • 打印日志

  • 处理异常

3️⃣ 响应方法(Response)

方法 作用
res.send() 返回任意数据
res.json() 返回 JSON
res.status() 设置状态码
res.end() 结束响应

五、Node.js 的 fs 文件读写

1、什么是 fs?

fs= File System(文件系统)

👉 用来 读文件 / 写文件 / 改文件名 / 删文件

✅ Node.js 内置模块,不需要安装

2、具体步骤

第一步:引入 fs 模块

javascript 复制代码
const fs = require('fs')

第二步:准备测试文件

在项目中新建一个文件,如test.txt。

javascript 复制代码
//test.txt中写
Hello Node.js
我是 fs 模块

第三步:同步 vs 异步(必须先懂)

类型 特点
同步 阻塞代码(不推荐)
异步 非阻塞(✅ 推荐)

⚠️ Node.js 核心是异步,尽量用异步

文件读取(最重要)

1️⃣ 异步读取(推荐 ✅)

javascript 复制代码
fs.readFile('test.txt', 'utf8', (err, data) => {
  if (err) {
    console.log('读取失败:', err)
    return
  }
  console.log('文件内容:', data)
})

✅ 运行:

javascript 复制代码
node app.js

✅ 输出:

javascript 复制代码
文件内容: Hello Node.js
我是 fs 模块

2️⃣ 同步读取(了解即可 ❌)

javascript 复制代码
const data = fs.readFileSync('test.txt', 'utf8')
console.log(data)

文件写入(非常重要)

1️⃣ 覆盖写入

javascript 复制代码
fs.writeFile('test.txt', '这是新写入的内容', err => {
  //如果出错了,就把错误抛出来,让程序停下来并报错
  if (err) throw err
  console.log('写入成功')
})

特点

  • 文件存在 → 覆盖

  • 文件不存在 → 新建

2️⃣ 追加写入(不覆盖)

javascript 复制代码
fs.appendFile('test.txt', '\n这是追加的内容', err => {
  if (err) throw err
  console.log('追加成功')
})

判断文件是否存在?

javascript 复制代码
fs.promises.access('test.txt')
  .then(() => console.log('文件存在'))
  .catch(() => console.log('文件不存在'))

重命名文件

javascript 复制代码
fs.rename('test.txt', 'new.txt', err => {
  if (err) throw err
  console.log('重命名成功')
})

删除文件

javascript 复制代码
fs.unlink('new.txt', err => {
  if (err) throw err
  console.log('删除成功')
})

完整示例:

javascript 复制代码
const fs = require('fs').promises
const handleFile = async () => {
try {
const data = await fs.readFile('test.txt', 'utf8')
console.log('读取成功:', data)
await fs.writeFile('test.txt', 'async/await 写法')
console.log('写入成功')
} catch (err) {
console.log('出错:', err)
}
}
handleFile()

六、Node.js 的 path 路径处理

1、什么是 path?

path是 Node.js 的 内置模块,专门用来 处理文件和目录路径。

2、为什么需要它?

不同操作系统路径分隔符不同

Windows:C:\Users\Admin\file.txt

Linux / Mac:/home/admin/file.txt

手写路径容易出错,拼接路径很麻烦,👉 path 帮你统一解决这些问题

3、具体步骤

第一步:引入 path 模块

javascript 复制代码
const path = require('path')

拼接路径 : path.join()(✅ 必会)

javascript 复制代码
const fullPath = path.join('public', 'images', 'logo.png')
console.log(fullPath)
//不同系统输出:
//Windows	public\images\logo.png
//Linux / Mac	public/images/logo.png
//自动适配系统,不会写死分隔符

解析绝对路径 :path.resolve()

javascript 复制代码
const absolutePath = path.resolve('uploads', 'file.png')
console.log(absolutePath)
//👉 从根目录开始解析路径
//✅ 常用于:
//配置文件
//静态资源根目录

获取文件名 :path.basename()

javascript 复制代码
const file = '/user/local/app.js'
console.log(path.basename(file))     // app.js
console.log(path.basename(file, '.js')) // app

获取目录名 :path.dirname()(✅ 必会)

javascript 复制代码
const file = '/user/local/app.js'
console.log(path.dirname(file)) // /user/local

获取文件后缀 :path.extname()(会用)

javascript 复制代码
const file = 'image.png'
console.log(path.extname(file)) // .png

解析路径对象 :path.parse()(了解)

javascript 复制代码
const file = '/user/local/app.js'
console.log(path.parse(file))
//输出:
//{
//    root: '/',
//    dir: '/user/local',
//    base: 'app.js',
//    ext: '.js',
//    name: 'app'
//}

前端转全栈必须记住的 3 个组合

1️⃣ 读取当前目录文件

javascript 复制代码
path.join(__dirname, 'config.json')

2️⃣ 静态资源路径(Express)

javascript 复制代码
path.join(__dirname, 'public')

3️⃣ 文件上传保存路径

javascript 复制代码
path.join(__dirname, 'uploads', Date.now() + '.png')

七、Node.js 的 url 解析

1、什么是 url 模块?

url是 Node.js 的 内置模块,用来 解析和处理 URL 地址。

2、为什么需要它?

从请求地址中拿到路径

获取 GET 参数

拼接 URL

避免手动字符串切割

3、具体步骤

第一步:引入 url 模块

javascript 复制代码
const url = require('url')

第二步:核心方法:url.parse()

作用:它可以把一个 URL 字符串,解析成一个对象。

javascript 复制代码
const url = require('url')
const reqUrl = 'http://localhost:3000/getinfo?id=1&name=tom'
const parsedUrl = url.parse(reqUrl, true) //第二个参数 true的作用:将字符串转化为对象
console.log(parsedUrl)
//解析后的对象结构如下:
//{
//  protocol: 'http:',
//  host: 'localhost:3000',
//  hostname: 'localhost',
//  port: '3000',
//  pathname: '/getinfo', //请求路径
//  query: { id: '1', name: 'tom' }, //GET 参数
//  search: '?id=1&name=tom' //URL 中的查询字符串
//}

八、Node.js 的 events 事件驱动

1、什么是 events 模块?

events = Node.js 的事件总线,所有异步操作都靠它通知完成。

2、具体步骤

第一步:引入 events 模块

javascript 复制代码
const EventEmitter = require('events')

第二步:创建事件发射器(核心)

javascript 复制代码
const EventEmitter = require('events')

// 创建事件发射器
const emitter = new EventEmitter()

//👉 emitter = 事件中心

第三步:监听事件(订阅)

javascript 复制代码
emitter.on('sayHi', () => {
  console.log('你好,Node.js')
})

第四步:触发事件(发布)

javascript 复制代码
emitter.emit('sayHi')

注:

1、带参数的事件(非常重要)

javascript 复制代码
emitter.on('login', (username, time) => {
  console.log(`${username} 登录成功,时间:${time}`)
})

emitter.emit('login', 'admin', '2026-01-21')

2、只执行一次的事件(once)

javascript 复制代码
emitter.once('init', () => {
  console.log('只执行一次')
})

emitter.emit('init')
emitter.emit('init')

3、移除事件监听(off)

javascript 复制代码
const handler = () => {
  console.log('事件触发')
}

emitter.on('test', handler)

emitter.emit('test')

emitter.off('test', handler)

emitter.emit('test') // 无输出

九、Node.js 的 stream 大文件处理

1、什么是 stream?

stream是 Node.js 的 内置模块,用来 处理流式数据。

2、具体步骤

第一步:引入模块

javascript 复制代码
const fs = require('fs')

第二步:可读流(Readable)

javascript 复制代码
const readStream = fs.createReadStream('big.txt', 'utf8')

readStream.on('data', chunk => {
  console.log('收到一块数据:', chunk.length)
})

readStream.on('end', () => {
  console.log('读取完成')
})

第三步:可写流(Writable)

javascript 复制代码
const writeStream = fs.createWriteStream('copy.txt')

writeStream.write('Hello\n')
writeStream.write('Node.js\n')
writeStream.end()

第四步:管道(pipe)------ 核心中的核心

javascript 复制代码
//文件拷贝(最常用)
const readStream = fs.createReadStream('big.txt')
const writeStream = fs.createWriteStream('copy.txt')

readStream.pipe(writeStream)

十、后端框架 Express 的学习

Express = Node.js 的"语法糖",让你用最少代码写最稳的后端接口。

1、Express 核心(必须精通)

知识点 为什么重要
**中间件(Middleware)**​ ✅ Express 的灵魂
**路由(Router)**​ ✅ 接口组织方式
**请求对象(req)**​ ✅ 获取参数
**响应对象(res)**​ ✅ 返回数据
错误处理 ✅ 防止服务器崩溃

2、具体步骤

第一步:如何使用Express搭建服务器?

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

app.get('/', (req, res) => {
  res.send('你好 Express')
})

app.listen(3000, () => {
  console.log('服务器启动:http://localhost:3000')
})

第二步:中间件(最重要 ⭐⭐⭐⭐⭐)

1️⃣ 什么是中间件?

中间件 = 请求到达接口前的"拦截器"

javascript 复制代码
app.use((req, res, next) => {
  console.log('有人访问了服务器')
  next() // 放行
})

2️⃣ 内置中间件(必会)

javascript 复制代码
// 解析 JSON
app.use(express.json())

// 解析表单
app.use(express.urlencoded({ extended: true }))

// 静态资源
app.use(express.static('public'))

第三步:路由(Router)

1️⃣ 基础路由

javascript 复制代码
app.get('/users', (req, res) => {})
app.post('/login', (req, res) => {})

2️⃣ 路由模块化(推荐)

javascript 复制代码
// routes/user.js
const router = express.Router()

router.get('/', (req, res) => {
  res.send('用户列表')
})

module.exports = router
javascript 复制代码
// app.js
const userRouter = require('./routes/user')
app.use('/users', userRouter)

第四步:请求参数(req.xxx

来源 写法
URL 参数 req.params.id
Query req.query.name
Body req.body
Header req.headers
javascript 复制代码
app.get('/user/:id', (req, res) => {
  res.json({
    id: req.params.id,
    name: req.query.name
  })
})

第五步:响应方法(res.xxx

方法 作用
res.send() 返回任意数据
res.json() 返回 JSON
res.status() 设置状态码
res.end() 结束响应

第六步:文件上传(替代原生 stream)

1️⃣ 安装 multer

javascript 复制代码
npm install multer

2️⃣ 上传代码(超简单)

javascript 复制代码
const multer = require('multer')
const upload = multer({ dest: 'uploads/' })

app.post('/upload', upload.single('file'), (req, res) => {
  res.send('上传成功')
})

第七步:静态资源服务器(一行搞定)

javascript 复制代码
app.use(express.static('dist'))

第八步:错误处理(统一兜底)

javascript 复制代码
app.use((err, req, res, next) => {
  console.error(err.stack)
  res.status(500).send('服务器出错了')
})

第九步:Express 必装依赖清单

javascript 复制代码
npm install express
npm install cors        # 跨域
npm install morgan     # 日志
npm install multer     # 上传
npm install dotenv     # 环境变量

十一、后端数据库 MongoDB 的学习

数据库 类型 适合前端的原因 推荐指数
MongoDB 文档型 数据结构是 JSON 对象,和 JS 无缝衔接,入门极快。 ⭐⭐⭐⭐⭐ (首选)
MySQL 关系型 最经典、最稳定,几乎所有公司都用,面试必问。 ⭐⭐⭐⭐⭐ (必学)
Redis 缓存型 存 Token、验证码,速度快到飞起。 ⭐⭐⭐⭐ (进阶)

1️⃣ 安装驱动

javascript 复制代码
npm install mongoose

2️⃣ 连接数据库

javascript 复制代码
const mongoose = require('mongoose');
mongoose.connect('mongodb://localhost:27017/myblog');

3️⃣ 定义"模型"(Schema)

javascript 复制代码
// 定义一个 User 模型
const UserSchema = new mongoose.Schema({
  username: String,
  password: String,
  age: Number
});

const User = mongoose.model('User', UserSchema);

4️⃣ 在接口中进行 CRUD(增删改查)

javascript 复制代码
// 创建一个用户(Create)
app.post('/user', async (req, res) => {
  const user = new User(req.body);
  await user.save(); // 保存到数据库
  res.send('用户创建成功');
});

// 查询所有用户(Read)
app.get('/users', async (req, res) => {
  const users = await User.find(); // 查询数据库
  res.json(users);
});

十二、后端数据库 MySQL 的学习

1、MySQL 是什么?(一句话秒懂)

MySQL = 一个专门用来存数据的软件(Excel 表格)

前端概念 MySQL 概念
项目 **数据库 (Database)**​
JS 对象数组 **表 (Table)**​
数组里的对象 **行 (Row)**​
对象的属性 列 (Column)

2、安装 MySQL(最简单方式)

✅ 推荐:Docker(一行命令,不污染电脑)

javascript 复制代码
docker run --name mysql-db -e MYSQL_ROOT_PASSWORD=123456 -p 3306:3306 -d mysql:8.0

3、Node.js 连接 MySQL(核心代码)

1️⃣ 安装依赖

javascript 复制代码
npm install mysql2

2️⃣ 创建连接(config.js)

javascript 复制代码
const mysql = require('mysql2/promise')

// 创建数据库连接池(高性能)
const pool = mysql.createPool({
  host: 'localhost',
  user: 'root',
  password: '123456',
  database: 'testdb', // 数据库名
  port: 3306
})

module.exports = pool

4、创建表(建 Excel 表头)

javascript 复制代码
//SQL 语句(必会)
CREATE TABLE users (
  id INT PRIMARY KEY AUTO_INCREMENT,
  username VARCHAR(50),
  password VARCHAR(100),
  age INT
)

5、Express + MySQL CRUD(增删改查)

1️⃣ 新增用户(Create)

javascript 复制代码
app.post('/user', async (req, res) => {
  const { username, password, age } = req.body

  const sql = 'INSERT INTO users (username, password, age) VALUES (?, ?, ?)'
  await pool.execute(sql, [username, password, age])

  res.send('用户创建成功')
})

2️⃣ 查询用户(Read)

javascript 复制代码
app.get('/users', async (req, res) => {
  const [rows] = await pool.execute('SELECT * FROM users')
  res.json(rows)
})

3️⃣ 更新用户(Update)

javascript 复制代码
app.put('/user/:id', async (req, res) => {
  const { username } = req.body
  const { id } = req.params

  await pool.execute(
    'UPDATE users SET username = ? WHERE id = ?',
    [username, id]
  )

  res.send('更新成功')
})

4️⃣ 删除用户(Delete)

javascript 复制代码
app.delete('/user/:id', async (req, res) => {
  const { id } = req.params
  await pool.execute('DELETE FROM users WHERE id = ?', [id])
  res.send('删除成功')
})

十三、后端数据库 Redis 的学习

1、Redis 是什么?(一句话秒懂)

Redis = 服务器的"超级内存缓存",用来存临时、高频访问的数据。

2、具体步骤

第一步:安装 Redis(最简单方式)

✅ Docker(推荐)

javascript 复制代码
docker run --name redis-cache -p 6379:6379 -d redis:alpine

第二步:Node.js 连接 Redis

1️⃣ 安装依赖

javascript 复制代码
npm install ioredis

2️⃣ 创建连接(redis.js)

javascript 复制代码
const Redis = require('ioredis')

const redis = new Redis({
  host: 'localhost',
  port: 6379
})

module.exports = redis

第三步:Redis 基本操作(5 分钟上手)

1️⃣ 存数据(SET)

javascript 复制代码
await redis.set('username', 'admin')

2️⃣ 取数据(GET)

javascript 复制代码
const username = await redis.get('username')
console.log(username) // admin

3️⃣ 设置过期时间(EXPIRE)

javascript 复制代码
await redis.set('code', '123456', 'EX', 60) // 60 秒后自动删除

4️⃣ 删除数据(DEL)

javascript 复制代码
await redis.del('username')

十四、JWT 登录鉴权 + 密码加密(全栈教程)

1、为什么要 JWT + 加密?

问题 后果
明文存密码 数据库泄露 = 全部账号被盗
接口无保护 任何人都能调用删除接口

2、技术分工(先搞清职责)

技术 作用
bcrypt ✅ 加密密码(不可逆)
JWT ✅ 生成登录凭证(Token)
中间件 ✅ 验证 Token 是否有效

3、安装依赖

javascript 复制代码
npm install express mysql2 bcrypt jsonwebtoken cors

4、数据库表结构(users)

javascript 复制代码
CREATE TABLE users (
  id INT PRIMARY KEY AUTO_INCREMENT,
  username VARCHAR(50) UNIQUE,
  password VARCHAR(255), -- 存加密后的密码
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
)

5、密码加密(bcrypt)

1️⃣ 注册接口(核心代码)

javascript 复制代码
const bcrypt = require('bcrypt')

app.post('/register', async (req, res) => {
  const { username, password } = req.body

  // 1. 生成盐(随机字符串)
  const saltRounds = 10
  const hashedPassword = await bcrypt.hash(password, saltRounds)

  // 2. 存入数据库
  const sql = 'INSERT INTO users (username, password) VALUES (?, ?)'
  await pool.execute(sql, [username, hashedPassword])

  res.send('注册成功')
})

//数据库中存的不是明文密码,而是加密串

2️⃣ 密码比对(登录时用)

javascript 复制代码
const isMatch = await bcrypt.compare(plainPassword, hashedPassword)

6、JWT 生成 Token

1️⃣ 登录接口

javascript 复制代码
const jwt = require('jsonwebtoken')

app.post('/login', async (req, res) => {
  const { username, password } = req.body

  // 1. 查用户
  const [rows] = await pool.execute(
    'SELECT * FROM users WHERE username = ?',
    [username]
  )

  if (rows.length === 0) {
    return res.status(400).send('用户不存在')
  }

  const user = rows[0]

  // 2. 验证密码
  const isMatch = await bcrypt.compare(password, user.password)
  if (!isMatch) {
    return res.status(400).send('密码错误')
  }

  // 3. 生成 JWT
  const token = jwt.sign(
    { userId: user.id, username: user.username },
    'secret_key', // 密钥(生产环境放环境变量)
    { expiresIn: '1h' }
  )

  res.json({ token })
})

//前端拿到 Token 后存到 localStorage

7、JWT 验证中间件(重点 ⭐⭐⭐⭐⭐)

1️⃣ 创建鉴权中间件

javascript 复制代码
const authMiddleware = (req, res, next) => {
  const token = req.headers.authorization?.split(' ')[1]

  if (!token) {
    return res.status(401).send('未登录')
  }

  try {
    const decoded = jwt.verify(token, 'secret_key')
    req.user = decoded // 把用户信息挂在 req 上
    next()
  } catch (err) {
    res.status(401).send('Token 无效或过期')
  }
}

2️⃣ 保护接口

javascript 复制代码
// 只有登录用户才能访问
app.get('/profile', authMiddleware, (req, res) => {
  res.json({
    msg: '这是受保护的接口',
    user: req.user
  })
})

8、JWT 工作流程(面试必背)

  1. 用户输入账号密码

  2. 后端验证密码(bcrypt.compare)

  3. 验证通过 → 生成 JWT

  4. 前端保存 Token

  5. 后续请求携带 Token

  6. 后端中间件验证 Token

十五、RESTful API + Swagger 教程(前端转全栈版)

1、什么是 RESTful?(一句话秒懂)

RESTful = 用 URL 表示资源,用 HTTP 动词表示方法

2、Express 实现 RESTful 接口

1️⃣ 用户路由(user.js)

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

// GET /users
router.get('/', (req, res) => {
  res.json({ msg: '用户列表' })
})

// GET /users/:id
router.get('/:id', (req, res) => {
  res.json({ id: req.params.id })
})

// POST /users
router.post('/', (req, res) => {
  res.json({ msg: '创建成功' })
})

// PUT /users/:id
router.put('/:id', (req, res) => {
  res.json({ msg: '更新成功' })
})

// DELETE /users/:id
router.delete('/:id', (req, res) => {
  res.json({ msg: '删除成功' })
})

module.exports = router

2️⃣ 注册路由(app.js)

javascript 复制代码
const userRouter = require('./routes/user')
app.use('/users', userRouter)

3、什么是 Swagger?(前端视角)

Swagger = 后端接口的"说明书 + 调试工具"

4、安装 Swagger

javascript 复制代码
npm install swagger-jsdoc swagger-ui-express

5、配置 Swagger

1️⃣ swagger.js

javascript 复制代码
const swaggerJsDoc = require('swagger-jsdoc')
const swaggerUi = require('swagger-ui-express')

const options = {
  definition: {
    openapi: '3.0.0',
    info: {
      title: '用户管理 API',
      version: '1.0.0',
      description: 'RESTful API 文档'
    }
  },
  apis: ['./routes/*.js'] // 接口文件路径
}

const swaggerSpec = swaggerJsDoc(options)

module.exports = (app) => {
  app.use('/api-docs', swaggerUi.serve, swaggerUi.setup(swaggerSpec))
}

2️⃣ 启用 Swagger(app.js)

javascript 复制代码
const setupSwagger = require('./swagger')
setupSwagger(app)

✅ 访问:

javascript 复制代码
http://localhost:3000/api-docs

6、给接口写 Swagger 注释(重点 ⭐⭐⭐⭐⭐)

✅ 查询用户列表

javascript 复制代码
/**
 * @swagger
 * /users:
 *   get:
 *     summary: 获取用户列表
 *     responses:
 *       200:
 *         description: 成功
 */
router.get('/', (req, res) => {})

✅ 创建用户

javascript 复制代码
/**
 * @swagger
 * /users:
 *   post:
 *     summary: 创建用户
 *     requestBody:
 *       required: true
 *       content:
 *         application/json:
 *           schema:
 *             type: object
 *             properties:
 *               username:
 *                 type: string
 *               password:
 *                 type: string
 *     responses:
 *       200:
 *         description: 创建成功
 */
router.post('/', (req, res) => {})

✅ 路径参数

javascript 复制代码
/**
 * @swagger
 * /users/{id}:
 *   get:
 *     summary: 获取用户详情
 *     parameters:
 *       - in: path
 *         name: id
 *         required: true
 *         schema:
 *           type: integer
 */
router.get('/:id', (req, res) => {})

十六、 MVC 架构 + 中间件教程(前端转全栈版)

1、为什么要用 MVC?(痛点)

javascript 复制代码
app.post('/login', async (req, res) => {
  // 1. 校验参数
  // 2. 查数据库
  // 3. 比对密码
  // 4. 生成 Token
  // 5. 返回结果
})

👉 问题:

  • 一个文件几百行

  • 代码无法复用

  • 改一处崩一片

2、MVC 是什么?(前端类比)

后端 MVC 前端类比 职责
Model API 数据源 处理数据(数据库)
View 页面组件 返回数据(JSON)
Controller 事件处理函数 业务逻辑

3、项目目录结构(标准写法)

4、MVC 实战:用户登录

1️⃣ Model(数据层)

javascript 复制代码
// models/userModel.js
const pool = require('../config/db')

class UserModel {
  static async findByUsername(username) {
    const [rows] = await pool.execute(
      'SELECT * FROM users WHERE username = ?',
      [username]
    )
    return rows[0]
  }
}

module.exports = UserModel

2️⃣ Service(业务层)

javascript 复制代码
// services/userService.js
const UserModel = require('../models/userModel')
const bcrypt = require('bcrypt')
const jwt = require('jsonwebtoken')

class UserService {
  static async login(username, password) {
    const user = await UserModel.findByUsername(username)

    if (!user) {
      throw new Error('用户不存在')
    }

    const isMatch = await bcrypt.compare(password, user.password)

    if (!isMatch) {
      throw new Error('密码错误')
    }

    const token = jwt.sign(
      { userId: user.id },
      'secret',
      { expiresIn: '1h' }
    )

    return { token }
  }
}

module.exports = UserService

3️⃣ Controller(控制层)

javascript 复制代码
// controllers/userController.js
const UserService = require('../services/userService')

class UserController {
  static async login(req, res) {
    try {
      const { username, password } = req.body
      const result = await UserService.login(username, password)
      res.json(result)
    } catch (error) {
      res.status(400).json({ msg: error.message })
    }
  }
}

module.exports = UserController

4️⃣ Route(路由层)

javascript 复制代码
// routes/user.js
const express = require('express')
const router = express.Router()
const UserController = require('../controllers/userController')

router.post('/login', UserController.login)

module.exports = router

5、什么是中间件?(前端拦截器)中间件 = 请求到达接口前的"安检"

javascript 复制代码
app.use((req, res, next) => {
  console.log('有人访问了')
  next() // 放行
})

6、JWT 鉴权中间件(实战)

1️⃣ 创建中间件

javascript 复制代码
// middlewares/auth.js
const jwt = require('jsonwebtoken')

const authMiddleware = (req, res, next) => {
  const token = req.headers.authorization?.split(' ')[1]

  if (!token) {
    return res.status(401).send('未登录')
  }

  try {
    const decoded = jwt.verify(token, 'secret')
    req.user = decoded
    next()
  } catch (err) {
    res.status(401).send('Token 无效')
  }
}

module.exports = authMiddleware

2️⃣ 使用中间件

javascript 复制代码
// routes/user.js
const authMiddleware = require('../middlewares/auth')

router.get('/profile', authMiddleware, (req, res) => {
  res.json({ user: req.user })
})

7、MVC 请求流程(必背)

十七、Linux + Docker 零基础教程(前端转全栈版)

1、为什么前端要学 Linux & Docker?

场景 痛点
本地能跑,服务器报错 环境不一致
依赖冲突 Node 版本不对
服务器被黑 不懂 Linux 命令
部署麻烦 手动配置太累

👉 Docker 解决环境问题,Linux 解决服务器问题

2、Linux 基础(必会 10 个命令)

1️⃣ 进入目录

javascript 复制代码
cd /home/project

2️⃣ 查看文件

javascript 复制代码
ls
ll

3️⃣ 创建文件夹

javascript 复制代码
mkdir project

4️⃣ 编辑文件

javascript 复制代码
vim app.js

5️⃣ 查看进程

javascript 复制代码
ps -ef | grep node

6️⃣ 杀死进程

javascript 复制代码
kill -9 12345

7️⃣ 查看端口

javascript 复制代码
netstat -tlnp | grep 3000

8️⃣ 下载文件

javascript 复制代码
wget https://xxx.tar.gz

9️⃣ 解压

javascript 复制代码
tar -zxvf xxx.tar.gz

🔟 查看日志

javascript 复制代码
tail -f app.log

3、Docker 是什么?(前端类比)

Docker = 手机里的"虚拟机"

前端 Docker
Chrome 镜像(Image)
打开网页 容器(Container)
插件 Dockerfile

4、Docker 安装

javascript 复制代码
curl -fsSL https://get.docker.com | sh

5、Docker 三大核心(必会)

概念 作用
Image 模板(安装包)
Container 运行的实例
Dockerfile 构建脚本

6、Docker 常用命令(背下来)

✅ 查看镜像

javascript 复制代码
docker images

✅ 查看容器

javascript 复制代码
docker ps
docker ps -a

✅ 启动容器

javascript 复制代码
docker run -d -p 3000:3000 --name my-app my-image

✅ 停止容器

javascript 复制代码
docker stop my-app

✅ 删除容器

javascript 复制代码
docker rm my-app

✅ 查看日志

javascript 复制代码
docker logs -f my-app

7、Dockerfile(构建 Node.js 项目)

1️⃣ 项目结构

2️⃣ Dockerfile

javascript 复制代码
FROM node:18-alpine

WORKDIR /app

COPY package*.json ./

RUN npm install --production

COPY . .

EXPOSE 3000

CMD ["node", "app.js"]

3️⃣ .dockerignore

4️⃣ 构建镜像

javascript 复制代码
docker build -t my-node-app .

5️⃣ 运行容器

javascript 复制代码
docker run -d -p 3000:3000 --name my-app my-node-app

✅ 访问:

javascript 复制代码
http://服务器IP:3000

8、Docker Compose(一键部署)

✅ docker-compose.yml

javascript 复制代码
version: '3'
services:
  app:
    build: .
    ports:
      - "3000:3000"
    depends_on:
      - mysql
      - redis

  mysql:
    image: mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD: 123456
    volumes:
      - mysql-data:/var/lib/mysql

  redis:
    image: redis:alpine

volumes:
  mysql-data:

✅ 启动

javascript 复制代码
docker-compose up -d

十八、CORS 跨域解决方案(前端转全栈版)

1、什么是 CORS?(一句话秒懂)

CORS = 浏览器的"安全门禁"

2、Express 解决 CORS(3 种方式)

✅ 方式 1:手写中间件(理解原理)

javascript 复制代码
app.use((req, res, next) => {
  res.setHeader('Access-Control-Allow-Origin', '*')
  res.setHeader('Access-Control-Allow-Methods', 'GET,POST,PUT,DELETE')
  res.setHeader('Access-Control-Allow-Headers', 'Content-Type,Authorization')
  next()
})

✅ 方式 2:使用 cors 包(✅ 推荐)

javascript 复制代码
npm install cors
javascript 复制代码
const cors = require('cors')

// 允许所有域名
app.use(cors())

// 只允许特定域名
app.use(cors({
  origin: 'http://localhost:5173',
  credentials: true // 允许携带 Cookie
}))

✅ 方式 3:预检请求(OPTIONS)

javascript 复制代码
//浏览器在发送 PUT / DELETE / 自定义 Header​ 时,会先发一个 OPTIONS​ 请求探路。
app.options('*', cors())

3、前端需要注意的点(重点 ⭐⭐⭐⭐⭐)

1️⃣ 携带 Cookie / Token

javascript 复制代码
// 前端 Axios
axios.get('/api', {
  withCredentials: true, // 必须加
  headers: {
    Authorization: `Bearer ${token}`
  }
})

2️⃣ 后端必须配合

javascript 复制代码
app.use(cors({
  origin: 'http://localhost:5173',
  credentials: true // 必须加
}))

4、CORS 常见错误(避坑)

错误 原因 解决
No 'Access-Control-Allow-Origin' 后端没配 CORS 加 cors 中间件
Credentials flag is true 前端带了 Cookie 后端 credentials: true
Method not allowed 预检失败 处理 OPTIONS 请求

5、开发环境 vs 生产环境

环境 方案
开发环境 ✅ CORS 中间件
生产环境 ✅ Nginx 反向代理

6、Nginx 反向代理(生产环境推荐)

javascript 复制代码
location /api/ {
    proxy_pass http://backend:3000/;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
}
相关推荐
小弥儿1 小时前
GitHub今日热榜 | 2026-07-04
学习·开源·github
小心亦新1 小时前
STM32学习10---串口
stm32·嵌入式硬件·学习
十月的皮皮1 小时前
C语言学习学习笔记20260704-中缀表达式求值(双栈法)
c语言·笔记·学习
星夜夏空991 小时前
C++学习(3) —— C++输入输出流
c++·学习
星夜夏空992 小时前
C++学习(1) ——C与C++
c语言·c++·学习
24计网1王仔寿2 小时前
Linux 系统运维全栈学习路线|从 Shell 脚本到容器云 OpenStack 完整学习指南
linux·学习·openstack
weixin_423533992 小时前
AFSim学习-自定义Processor开发2-将平台状态存储到csv
学习
bu_shuo2 小时前
计算机二级学习-查找和排序
学习·算法·排序算法
爱奥尼欧2 小时前
轻量级可扩展日志框架-异步日志与系统集成
开发语言·数据库·c++·学习