上一篇文章我们讲了怎么用Node.js
原生API来写一个web服务器
,虽然代码比较丑,但是基本功能还是有的。但是一般我们不会直接用原生API来写,而是借助框架来做,比如本文要讲的Express
。通过上一篇文章的铺垫,我们可以猜测,Express
其实也没有什么黑魔法,也仅仅是原生API的封装,主要是用来提供更好的扩展性,使用起来更方便,代码更优雅。本文照例会从Express
的基本使用入手,然后自己手写一个Express
来替代他,也就是源码解析。
本文可运行代码已经上传GitHub,拿下来一边玩代码,一边看文章效果更佳:github.com/dennis-jian…
简单示例
使用Express
搭建一个最简单的Hello World
也是几行代码就可以搞定,下面这个例子来源官方文档:
const express = require('express'); const app = express(); const port = 3000; app.get('/', (req, res) => { res.send('Hello World!'); }); app.listen(port, () => { console.log(`Example app listening at http://localhost:${port}`); });
可以看到Express
的路由可以直接用app.get
这种方法来处理,比我们之前在http.createServer
里面写一堆if
优雅多了。我们用这种方式来改写下上一篇文章的代码:
const path = require("path"); const express = require("express"); const fs = require("fs"); const url = require("url"); const app = express(); const port = 3000; app.get("/", (req, res) => { res.end("Hello World"); }); app.get("/api/users", (req, res) => { const resData = [ { id: 1, name: "小明", age: 18, }, { id: 2, name: "小红", age: 19, }, ]; res.setHeader("Content-Type", "application/json"); res.end(JSON.stringify(resData)); }); app.post("/api/users", (req, res) => { let postData = ""; req.on("data", (chunk) => { postData = postData + chunk; }); req.on("end", () => { // 数据传完后往db.txt插入内容 fs.appendFile(path.join(__dirname, "db.txt"), postData, () => { res.end(postData); // 数据写完后将数据再次返回 }); }); }); app.listen(port, () => { console.log(`Server is running on http://localhost:${port}/`); });
Express
还支持中间件,我们写个中间件来打印出每次请求的路径:
app.use((req, res, next) => { const urlObject = url.parse(req.url); const { pathname } = urlObject; console.log(`request path: ${pathname}`); next(); });
Express
也支持静态资源托管,不过他的API是需要指定一个文件夹来单独存放静态资源的,比如我们新建一个public
文件夹来存放静态资源,使用express.static
中间件配置一下就行:
app.use(express.static(path.join(__dirname, 'public')));
然后就可以拿到静态资源了: