一、Express路由进阶

1. Router路由模块化

当项目路由增多时,使用express.Router将路由拆分到独立文件:

// routes/user.js

const express = require('express');

const router = express.Router();

router.get('/', (req, res) => {

res.send('用户列表');

});

router.get('/:id', (req, res) => {

res.send(`用户详情: ${req.params.id}`);

});

module.exports = router;

// app.js

const express = require('express');

const app = express();

const userRouter = require('./routes/user');

app.use('/user', userRouter); // 挂载路由模块

app.listen(3000);

二、EJS模板引擎

1. EJS基础配置

const express = require('express');

const path = require('path');

const app = express();

// 设置模板引擎为EJS

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

// 设置模板文件存放目录

app.set('views', path.resolve(__dirname, './views'));

2. EJS常用语法

<!-- views/index.ejs -->

<!DOCTYPE html>

<html>

<head>

<title><%= title %></title>

</head>

<body>

<!-- 输出变量 -->

<h1><%= title %></h1>

<!-- 逻辑判断 -->

<% if (isLogin) { %>

<p>欢迎回来,<%= username %></p>

<% } else { %>

<p>请登录</p>

<% } %>

<!-- 循环遍历 -->

<ul>

<% list.forEach(item => { %>

<li><%= item.name %> - <%= item.price %>元</li>

<% }) %>

</ul>

</body>

</html>

3. 渲染页面

app.get('/index', (req, res) => {

res.render('index', {

title: '商品列表',

isLogin: true,

username: '张三',

list: [

{ name: '苹果', price: 5 },

{ name: '香蕉', price: 3 }

]

});

});

三、MongoDB与Mongoose

1. MongoDB核心概念

概念

说明

对应关系型数据库

数据库(database)

数据容器

数据库

集合(collection)

文档组

表(table)

文档(document)

一条数据记录

行(row)

字段(field)

数据属性

列(column)

2. Mongoose连接与操作

const mongoose = require('mongoose');

// 连接数据库

mongoose.connect('mongodb://127.0.0.1:27017/project');

// 定义Schema(结构)

const userSchema = new mongoose.Schema({

username: { type: String, required: true },

age: { type: Number, default: 18 },

email: { type: String, unique: true },

createTime: { type: Date, default: Date.now }

});

// 创建Model(模型)

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

// CRUD操作

async function operate() {

// 创建

const user = await User.create({ username: '张三', age: 20, email: 'zs@qq.com' });

// 查询

const users = await User.find({ age: { $gte: 18 } }); // 年龄>=18

// 更新

await User.updateOne({ username: '张三' }, { age: 21 });

// 删除

await User.deleteOne({ username: '张三' });

}

3. 条件控制与个性化读取

// 运算符:$gt(>), $gte(>=), $lt(<), $lte(<=), $ne(!=), $in, $nin

await User.find({ age: { $gte: 18, $lte: 60 } });

// 逻辑运算:$and, $or, $not

await User.find({ $or: [{ age: { $lt: 18 } }, { age: { $gt: 60 } }] });

// 正则匹配

await User.find({ username: /^张/ }); // 姓张的

// 个性化读取:select选择字段,sort排序,skip/limit分页

await User.find()

.select('username age -_id') // 只取username和age,排除_id

.sort({ age: -1 }) // 按年龄降序

.skip(10) // 跳过前10条

.limit(10); // 取10条

四、API接口与RESTful规范

1. RESTful API设计

操作

HTTP方法

URL路径

说明

查询所有

GET

/api/users

获取用户列表

查询单个

GET

/api/users/:id

获取指定用户

创建

POST

/api/users

新增用户

更新

PUT/PATCH

/api/users/:id

修改用户信息

删除

DELETE

/api/users/:id

删除用户

2. 接口实现示例

const express = require('express');

const router = express.Router();

const User = require('../models/user');

// 查询所有

ter.get('/users', arousync (req, res) => {

const users = await User.find();

res.json({ code: 200, data: users });

});

// 查询单个

router.get('/users/:id', async (req, res) => {

const user = await User.findById(req.params.id);

if (!user) return res.status(404).json({ code: 404, msg: '用户不存在' });

res.json({ code: 200, data: user });

});

// 创建

router.post('/users', async (req, res) => {

const user = await User.create(req.body);

res.status(201).json({ code: 201, data: user });

});

// 更新

router.put('/users/:id', async (req, res) => {

await User.updateOne({ _id: req.params.id }, req.body);

res.json({ code: 200, msg: '更新成功' });

});

// 删除

router.delete('/users/:id', async (req, res) => {

await User.deleteOne({ _id: req.params.id });

res.json({ code: 200, msg: '删除成功' });

});

module.exports = router;

五、会话控制

1. Cookie

const express = require('express');

const cookieParser = require('cookie-parser');

const app = express();

app.use(cookieParser());

// 设置cookie

app.get('/set-cookie', (req, res) => {

res.cookie('username', '张三', { maxAge: 1000 * 60 * 60 }); // 1小时

res.send('Cookie已设置');

});

// 获取cookie

app.get('/get-cookie', (req, res) => {

console.log(req.cookies); // { username: '张三' }

res.send(req.cookies);

});

// 删除cookie

app.get('/del-cookie', (req, res) => {

res.clearCookie('username');

res.send('Cookie已删除');

});

2. Session

const session = require('express-session');

const MongoStore = require('connect-mongo');

app.use(session({

name: 'sid',

secret: 'atguigu',

saveUninitialized: false,

resave: true,

store: MongoStore.create({

mongoUrl: 'mongodb://127.0.0.1:27017/project'

}),

cookie: {

httpOnly: true,

maxAge: 1000 * 60 * 30 // 30分钟

}

}));

// 登录设置session

app.get('/login', (req, res) => {

if (req.query.username === 'admin' && req.query.password === '123') {

req.session.username = 'admin';

req.session.uid = '001';

res.send('登录成功');

} else {

res.status(401).send('登录失败');

}

});

// 验证session

app.get('/cart', (req, res) => {

if (req.session.username) {

res.send(`购物车页面 - 当前用户: ${req.session.username}`);

} else {

res.status(401).send('请先登录');

}

});

// 销毁session

app.get('/logout', (req, res) => {

req.session.destroy(() => {

res.send('退出成功');

});

});

3. Session vs Cookie vs Token

特性

Cookie

Session

Token

存储位置

浏览器端

服务器端

客户端(通常localStorage)

安全性

低(明文)

较高

高(加密签名)

服务器压力

有(存储数据)

传输量

大(携带所有数据)

小(只传ID)

存储限制

4KB

无限制

无限制

适用场景

简单标识

传统Web应用

移动端/前后端分离

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐