面试题答案
一键面试性能优化
- 路由设计
- 模块化路由:将不同功能的路由拆分成独立的模块,提高代码的可维护性和可扩展性。例如,将用户相关路由放在
userRoutes.js
,商品相关路由放在productRoutes.js
等。
// userRoutes.js const express = require('express'); const router = express.Router(); router.get('/users', (req, res) => { // 处理获取用户列表逻辑 res.send('User list'); }); router.post('/users', (req, res) => { // 处理创建用户逻辑 res.send('User created'); }); module.exports = router;
- 减少路由层级:避免过深的路由嵌套,减少匹配时间。例如,
/api/v1/users/profile
比/api/v1/user/profile/userInfo
更好。
- 模块化路由:将不同功能的路由拆分成独立的模块,提高代码的可维护性和可扩展性。例如,将用户相关路由放在
- 中间件使用
- 全局中间件:合理使用全局中间件,比如
express.json()
用于解析 JSON 格式的请求体,express.urlencoded()
用于解析 URL 编码格式的请求体。
const express = require('express'); const app = express(); app.use(express.json()); app.use(express.urlencoded({ extended: true }));
- 特定路由中间件:对于特定路由,可以使用中间件进行权限验证、日志记录等。例如,只有登录用户才能访问
/users/profile
路由。
const authMiddleware = (req, res, next) => { // 模拟验证逻辑 if (req.headers.authorization === 'valid_token') { next(); } else { res.status(401).send('Unauthorized'); } }; app.get('/users/profile', authMiddleware, (req, res) => { res.send('User profile'); });
- 全局中间件:合理使用全局中间件,比如
- 缓存策略
- 内存缓存:使用
node-cache
等库进行简单的内存缓存。对于不经常变化的 GET 请求数据,可以进行缓存。
const NodeCache = require('node-cache'); const myCache = new NodeCache(); app.get('/cached-data', (req, res) => { const cachedData = myCache.get('cachedDataKey'); if (cachedData) { res.send(cachedData); } else { // 从数据库或其他数据源获取数据 const newData = 'Some data'; myCache.set('cachedDataKey', newData); res.send(newData); } });
- HTTP 缓存:设置合适的 HTTP 缓存头,如
Cache - Control
和ETag
。对于静态资源,可以设置较长的缓存时间。
app.get('/static - file', (req, res) => { res.set('Cache - Control','public, max - age = 31536000'); // 缓存一年 res.sendFile(__dirname + '/public/file.js'); });
- 内存缓存:使用
确保 POST 请求数据安全性
- 防止 SQL 注入
- 使用参数化查询:如果使用 MySQL,使用
mysql2
库的参数化查询。
const mysql = require('mysql2'); const connection = mysql.createConnection({ host: 'localhost', user: 'root', password: 'password', database: 'test' }); app.post('/user - insert', (req, res) => { const { username, password } = req.body; const query = 'INSERT INTO users (username, password) VALUES (?,?)'; connection.query(query, [username, password], (error, results, fields) => { if (error) throw error; res.send('User inserted successfully'); }); });
- 使用参数化查询:如果使用 MySQL,使用
- 防止 XSS 攻击
- 输入过滤和转义:使用
DOMPurify
库对输入进行过滤和转义。
const express = require('express'); const DOMPurify = require('dompurify'); const app = express(); app.use(express.json()); app.post('/submit - comment', (req, res) => { const comment = req.body.comment; const cleanComment = DOMPurify.sanitize(comment); // 将 cleanComment 存储到数据库或进行其他处理 res.send('Comment submitted'); });
- 输入过滤和转义:使用