Express框架入门:从基础搭建到路由系统详解

发布时间:2026/7/22 4:07:45
Express框架入门:从基础搭建到路由系统详解 1. Express基础环境搭建与服务器创建作为Node.js最流行的Web框架之一Express让服务器开发变得异常简单。我们先从最基础的服务器搭建开始1.1 项目初始化与Express安装首先创建一个空目录作为项目根目录执行npm初始化命令mkdir express-demo cd express-demo npm init -y接着安装Express核心包npm install express --save提示使用--save参数会将依赖自动写入package.json这是现代Node.js项目的标准做法。如果是老版本npm(5.0之前)需要显式添加这个参数。1.2 创建基础服务器新建server.js作为入口文件写入以下代码const express require(express); const app express(); app.get(/, (req, res) { res.send(欢迎来到Express世界); }); app.listen(3000, () { console.log(服务器已启动访问地址http://localhost:3000); });这个最简单的Express服务器已经可以处理GET请求。相比原生Node.js的http模块Express用几行代码就实现了路由功能。1.3 开发工具配置为了提高开发效率建议安装nodemon工具npm install -g nodemon然后使用nodemon启动服务器nodemon server.jsnodemon会监控文件变化自动重启服务这在开发阶段非常实用。如果入口文件不是server.js而是app.js则需指定文件名nodemon app.js2. Express路由系统深度解析2.1 基础路由配置Express的路由定义非常直观基本语法是app.METHOD(PATH, HANDLER)其中METHOD可以是get/post/put/delete等HTTP方法PATH是URL路径HANDLER是处理函数示例app.get(/api/users, (req, res) { res.json([{id: 1, name: 张三}, {id: 2, name: 李四}]); });2.2 动态路由参数路由可以包含动态参数通过req.params获取app.get(/users/:userId/posts/:postId, (req, res) { console.log(req.params); // { userId: 123, postId: 456 } res.send(用户${req.params.userId}的文章${req.params.postId}); });2.3 路由正则匹配Express路由支持正则表达式提供更灵活的匹配方式// 匹配/acd或/abcd app.get(/ab?cd, (req, res) { res.send(匹配成功); }); // 匹配/1xx2其中x可以是任意字符 app.get(/1.*2, (req, res) { res.send(通配符匹配); });2.4 查询字符串处理对于URL中的查询参数(?keyvalue)Express自动解析并存入req.queryapp.get(/search, (req, res) { // 访问/search?qexpresspage2 console.log(req.query); // { q: express, page: 2 } res.send(搜索关键词${req.query.q}第${req.query.page}页); });3. 请求处理与数据获取3.1 GET请求处理GET请求是最常见的HTTP方法Express已经内置支持app.get(/products, (req, res) { const products [ {id: 1, name: 手机, price: 3999}, {id: 2, name: 笔记本, price: 5999} ]; res.json(products); });3.2 POST请求与body-parser处理POST请求需要body-parser中间件来解析请求体npm install body-parser --save使用示例const bodyParser require(body-parser); // 解析application/x-www-form-urlencoded app.use(bodyParser.urlencoded({ extended: false })); // 解析application/json app.use(bodyParser.json()); app.post(/login, (req, res) { console.log(req.body); // 获取POST数据 res.send(欢迎${req.body.username}); });注意extended: false表示使用querystring库解析URL编码数据true表示使用qs库。对于简单数据false即可。3.3 不同内容类型的处理可以为不同路由指定不同的解析器const jsonParser bodyParser.json(); const urlencodedParser bodyParser.urlencoded({ extended: false }); // 只处理JSON数据 app.post(/api/users, jsonParser, (req, res) { // ... }); // 只处理表单数据 app.post(/contact, urlencodedParser, (req, res) { // ... });4. 文件上传与multer中间件4.1 multer基础配置处理文件上传需要multer中间件npm install multer --save基本使用const multer require(multer); const upload multer({ dest: uploads/ }); app.post(/upload, upload.single(avatar), (req, res) { console.log(req.file); // 上传文件信息 res.send(上传成功); });对应的HTML表单form action/upload methodpost enctypemultipart/form-data input typefile nameavatar button typesubmit上传/button /form4.2 自定义存储配置multer允许自定义文件名和存储路径const storage multer.diskStorage({ destination: (req, file, cb) { cb(null, uploads/); }, filename: (req, file, cb) { const uniqueSuffix Date.now() - Math.round(Math.random() * 1E9); cb(null, file.fieldname - uniqueSuffix path.extname(file.originalname)); } }); const upload multer({ storage: storage });4.3 文件过滤与限制可以添加文件类型和大小限制const fileFilter (req, file, cb) { if (file.mimetype image/jpeg || file.mimetype image/png) { cb(null, true); } else { cb(new Error(只支持JPEG/PNG格式), false); } }; const upload multer({ storage: storage, limits: { fileSize: 1024 * 1024 * 5 // 限制5MB }, fileFilter: fileFilter });5. EJS模板引擎实战5.1 EJS基础配置安装EJS模板引擎npm install ejs --save配置Express使用EJSapp.set(views, path.join(__dirname, views)); app.set(view engine, ejs);5.2 基本模板渲染创建views/index.ejs!DOCTYPE html html head title% title %/title /head body h1% message %/h1 /body /html路由中渲染模板app.get(/, (req, res) { res.render(index, { title: Express首页, message: 欢迎使用EJS模板引擎 }); });5.3 模板逻辑控制EJS支持JavaScript逻辑% if (user) { % h2欢迎, % user.name %/h2 % } else { % a href/login请登录/a % } % ul % items.forEach(item { % li% item %/li % }) % /ul5.4 模板布局与包含创建公共头部views/partials/header.ejsheader nav a href/首页/a a href/about关于/a /nav /header在其他模板中包含%- include(partials/header) % main !-- 页面主要内容 -- /main6. 项目优化与最佳实践6.1 路由模块化将路由拆分到单独文件routes/users.jsconst 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;主文件中引入const userRoutes require(./routes/users); app.use(/users, userRoutes);6.2 错误处理中间件自定义错误处理// 404处理 app.use((req, res, next) { res.status(404).render(404); }); // 错误处理 app.use((err, req, res, next) { console.error(err.stack); res.status(500).render(500); });6.3 安全最佳实践重要安全措施const helmet require(helmet); app.use(helmet()); // 防止跨站请求伪造 const csrf require(csurf); app.use(csrf({ cookie: true })); // 限流保护 const rateLimit require(express-rate-limit); const limiter rateLimit({ windowMs: 15 * 60 * 1000, // 15分钟 max: 100 // 每个IP限制100次请求 }); app.use(limiter);6.4 性能优化技巧提升Express性能的方法// 启用gzip压缩 const compression require(compression); app.use(compression()); // 静态文件缓存 app.use(express.static(public, { maxAge: 1y, immutable: true })); // 集群模式 const cluster require(cluster); const numCPUs require(os).cpus().length; if (cluster.isMaster) { for (let i 0; i numCPUs; i) { cluster.fork(); } } else { // 启动Express应用 }7. 常见问题与解决方案7.1 跨域问题处理使用cors中间件解决跨域npm install cors --save配置示例const cors require(cors); // 允许所有来源 app.use(cors()); // 自定义配置 app.use(cors({ origin: https://example.com, methods: [GET, POST], allowedHeaders: [Content-Type] }));7.2 静态文件服务托管静态文件目录app.use(express.static(public)); // 可以添加多个静态目录 app.use(/uploads, express.static(uploads));7.3 会话管理使用express-session管理会话npm install express-session --save基本配置const session require(express-session); app.use(session({ secret: your-secret-key, resave: false, saveUninitialized: true, cookie: { secure: true } }));7.4 数据库集成连接MongoDB示例const mongoose require(mongoose); mongoose.connect(mongodb://localhost:27017/express-demo, { useNewUrlParser: true, useUnifiedTopology: true }); const User mongoose.model(User, { name: String, email: String }); app.post(/users, async (req, res) { const user new User(req.body); await user.save(); res.status(201).send(user); });8. 项目部署与生产环境配置8.1 环境变量管理使用dotenv管理环境变量npm install dotenv --save创建.env文件PORT3000 DB_URLmongodb://localhost:27017/prod-db SECRET_KEYyour-production-secret应用配置require(dotenv).config(); const port process.env.PORT || 3000; app.listen(port, () { console.log(服务器运行在${port}端口); });8.2 PM2进程管理使用PM2部署Node.js应用npm install pm2 -g pm2 start server.js --name express-app常用PM2命令pm2 list # 查看进程列表 pm2 logs # 查看日志 pm2 restart all # 重启所有应用 pm2 delete all # 删除所有应用8.3 Nginx反向代理配置Nginx作为反向代理server { listen 80; server_name example.com; location / { proxy_pass http://localhost:3000; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection upgrade; proxy_set_header Host $host; proxy_cache_bypass $http_upgrade; } }8.4 HTTPS配置使用Lets Encrypt免费SSL证书sudo apt install certbot python3-certbot-nginx sudo certbot --nginx -d example.comExpress中强制HTTPSapp.use((req, res, next) { if (!req.secure req.get(X-Forwarded-Proto) ! https process.env.NODE_ENV production) { return res.redirect(https:// req.get(Host) req.url); } next(); });在实际项目中Express的灵活性和丰富的中间件生态系统使其成为Node.js Web开发的首选框架。通过合理组织代码结构、选择适当的中间件和遵循最佳实践可以构建出高性能、易维护的Web应用。