为什么85%的开发者都在错误地使用Express.js?
Why 85% of Developers Use Express.js Wrongly
Express.js 已成为 Node.js 最受欢迎的 Web 框架之一,因其简洁性、灵活性和强大的生态系统而受到赞誉。然而,过于简单的特性可能会让一些开发人员产生过度自信,因此滥用 Express.js,导致性能、安全性和可扩展性受到影响。
1. 错误处理不当许多开发人员忽略了正确的错误处理机制,常常不一致地使用 try/catch
块,或者直接跳过错误中间件。这将导致:
- 未捕获的异常: 当异常发生时,应用程序会崩溃。
- 不安全的错误信息暴露: 在实际运行中,可能会泄露敏感错误信息。
实现一个集中式的错误处理中间件,例如:等等。
app.use((err, req, res, next) => {
console.error(err.stack);
res.status(500).json({ error: '出了一点小状况!' });
});
2. 低效使用中间件
Express 允许你使用中间件处理请求,但许多开发人员错误地使用它,比如:…
- 过度使用中间件:为每个路由都添加冗余的中间件,而不是全局或选择性地应用。
- 错误地排列中间件顺序:导致逻辑混乱。
策略性地部署中间件,根据需要将其应用在应用层面或路由层面如下:
// 全局应用中间件:
app.use(express.json());
// 仅在特定路由上应用中间件
app.use('/api', authenticateMiddleware); // 这里的中间件仅用于处理 '/api' 路由的请求
三. 未能有效优化性能
Express 是轻量级的,但不良的编码实践可能导致严重的性能瓶颈。
- 阻塞事件循环:在请求处理器中使用同步操作(例如
fs.readFileSync
)。 - 错误使用
async/await
: 忘记正确处理 Promise,导致未捕获的拒绝。
- 使用函数的异步版本。
- 将繁重的计算放到工作线程或外部服务。
在Express.js中,安全漏洞很常见,而且非常危险。
- 暴露敏感信息: 在响应中暴露堆栈跟踪或调试信息。
- 忽略安全头部: 未设置安全头部以防止XSS或点击劫持。
- 使用
helmet
来配置安全头信息
const helmet = require('helmet');
// 使用 helmet 来增强安全头信息
app.use(helmet());
确保输入安全,以避免注入攻击。
5 配置硬编码将 API 密钥、数据库凭证或环境特定配置信息直接写死到代码中是一种常见的错误。这很危险且不安全,也会妨碍应用程序的可移植性。
正确的做法:使用环境变量和配置管理工具,例如dotenv
。
require('dotenv').config(); // 初始化环境变量并加载 .env 文件
const dbUrl = process.env.DATABASE_URL; // 从环境变量中获取数据库 URL
6. 错误地结构应用
许多开发者倾向于使用单体代码结构,将所有代码放在一个 app.js
文件中,例如。这会导致:
- 难以管理的代码基: 难以调试或扩展性。
- 低可重用性: 难以拆分和重复利用组件。
采用模块化结构。
/routes
users.js 用户请求的路由文件
products.js 产品请求的路由文件
/controllers
userController.js 用户控制器文件
productController.js 产品控制器文件
routes 目录包含处理用户和产品请求的路由文件。controllers 目录包含用户和产品的控制器文件。
7. 忽略扩展性快递常被用作起点,但很多人没准备好扩展业务。常见的问题有:
- 状态服务: 将 session 数据存放在内存中,而不是使用类似 Redis 的共享存储。
- 不使用负载均衡: 运行单实例,未利用水平扩展。
- 使用无状态的 JWT 认证或共享存储库来存储会话数据。
- 将应用部署在负载均衡器后面。
许多开发者仅仅依赖 console.log()
进行调试,这使得在生产环境中诊断问题变得更加困难。
使用像 winston
或 pino
这样的日志库来实现结构化日志。
const winston = require('winston');
// 创建一个日志记录器,设置日志级别为'info',并使用控制台运输
const logger = winston.createLogger({ level: 'info', transports: [new winston.transports.Console()] });
// 在每次请求时,记录请求的方法和URL
app.use((req, res, next) => {
logger.info(`${req.method} ${req.url}`);
next();
});
9. 不正确使用异步/等待
不正确地处理异步代码可能会导致 bug,比如:
- 忘了使用
await
导致 Promise 无法解决。 - 用回调来代替 Promises 或者
async/await
。
始终用 async / await
并妥善处理错误:
app.get('/data', async (req, res, next) => {
try {
const 数据 = await 获取数据();
res.json(数据);
} catch (错误) {
next(错误);
}
});
10. 跳过这一步。
这类应用常常因测试不足而在实际运行中暴露出未被发现的问题。
正确的做法如下:使用像 Mocha
或 Jest
这样的工具来进行测试:
const request = require('supertest');
const app = require('../app');
// GET /users
// 应该返回用户列表
it(async () => {
const response = await request(app).get('/users');
expect(response.status).toBe(200);
});
结尾
Express.js 是一个出色的框架,但它的灵活性也是一把双刃剑。通过避免这些常见的陷阱,你可以构建安全、可扩展且高效维护的应用程序,从而充分发挥其真正的力量。采用最佳实践,你就能从那85%滥用它的人中脱颖而出!
你可能还会喜欢:
1) 你怎样优化网站的性能?你可以在这里了解更多:[链接]
3) 高级JavaScript Promise对象面试问题
"你能回答这个高级JavaScript Promise对象面试问题吗?"
5)Can AI Transform the Trading Landscape?
点击这里阅读更多我的博客这里
分享你的经历,咱们来聊聊怎么解决这些问题!
关注我领英
共同学习,写下你的评论
评论加载中...
作者其他优质文章