📘 欢迎关注博主的掘金:暮星的主页
前言
Nodejs 在主机层面上为运行 ECMAScript 提供了底层接口和功能,但这些接口和功能大多数都繁琐难用,所以我们一般不会直接用 Nodejs 原生的 http 模块去写一个服务器,而是直接使用封装过的第三方库。
Express 是众多 Node 服务器框架中功能强大且生态较好的一个,它在 Nodejs http 模块的基础上做了一层抽象,提供了更简单易用且高级的接口。
开始使用
安装:npm i -S express
使用 Express 构建 web 应用的第一步是创建 Express 实例,并开启端口监听。
const express = require('express');
// 创建 express 实例
const app = express();
// 定义要监听的端口号
const port = xxx;
// 开始监听端口
app.listen(port, () => {
console.log(`listen on &{port}`)
})
app.listen(port, ...)
让主机开始监听来自 port 端口的请求。有请求那就得有响应,于是下一步便是配置请求映射,使得当请求方法和请求路径均匹配时,交给对应的处理函数进行响应。
Express 实例对象上有很多用来处理请求且符合 REST 风格的方法,例如用 app.get()
处理 get 请求,用 app.post()
处理 post 请求等。
🚩 举个例子:
const express = require('express');
// 创建 express 实例
const app = express();
// 定义要监听的端口号
const port = 8080;
app.get('/name', (req, res) => {
console.log('请求处理中......')
})
// 开始监听端口
app.listen(port, () => {
console.log(`listen on ${port}`)
})
app.get('/name', (req, res) => {...})
意味着 Express 能够接收到对 Host-IP:8080/name
的请求,分别将请求信息对象和响应信息对象作为参数注入后面的回调函数并运行。
请求路径匹配
Express 中匹配请求的方式多种多样,编写 Express 应用的时候要格外注意使请求路径对应到正确的处理函数。
...
// 仅接收 get 请求
// 匹配路径:'/name'
// 不匹配路径:'/na'、'/name/123'、...
app.get('/name', (req, res) => {});
// 仅接收 delete 请求
// 匹配路径:'/name/person'
// 不匹配路径:'/na'、'/name/123'、...
app.delete('/name/person', (req, res) => {});
// 接收所有方法的请求
// 匹配路径:'/name'
// 不匹配路径:'/na'、'/name/123'、...
app.all('/name', (req, res) => {});
// 匹配任何路径
app.all('*', (req, res) => {});
// 匹配路径:'/te12st/name'、'/test/name'、...
// 不匹配路径:'/test'、'/test5/name'、...
app.all('/te**st/name', (req, res) => {});
...
没有匹配到的路径,会自动返回 404。
上面路径的写法都属于静态路径,在实际需求中,我们往往需要不同的请求路径由同一个处理函数响应,并且函数能识别 url 不同的那一部分,做对应处理。
对此,我们可以用语法 :xxx
来编写动态路径。
...
// 匹配路径:'/name/123'、'/name/ '、...
// 不匹配路径:'/name/1/a'、'/name/'、...
app.get('/name/:id', (req, res) => {});
...
Req
在处理请求的过程中,我们可以通过 Req 对象获取请求信息,常用的如下:
...
app.get('/test/:item/:name', (req, res) => {
// 获取请求的 url
console.log(req.originalUrl);
// 获取请求头
console.log(req.headers);
// 获取请求路径
console.log(req.path);
// 获取请求查询字符串的对象形式
console.log(req.query);
// 获取请求中匹配动态路径的参数组成的对象
console.log(req.params);
})
...
Res
处理请求的最关键一步就是响应,Express 是通过 Res 对象提供的各种方法来响应的。
其中最普通的响应方式就是 res.send()
,你可以用它返回字符串、对象、数组等等数据。它会自动设置响应头并根据返回的数据的格式修改 Content-Type
字段的值。
Express v4.8.0 以后还可以通过 res.sendFile() 把一个文件作为响应内容。
不用像写原生 http 模块那样,响应后要调用
end()
方法来结束该次响应,否则客户端就会一直处于等待响应的状态,res.send()
内部已经把调用end()
这步包含进去了。
// 返回一个 html,下面两种方法是等效的
const path = require('path');
const fs = require('fs');
const htmlPath = path.resolve(__dirname, './index.html');
...
app.get('/test/:item/:name', (req, res) => {
// method(1)
res.sendFile(htmlPath);
// method(2)
const content = fs.readFileSync(htmlPath, 'utf-8');
res.send(content);
});
...
Res 的更多功能如下:
...
app.get('/test/:item/:name', (req, res) => {
// 设置响应头字段(1)
res.setHeader('X-XSS-Protection', '1; mode=block');
// 设置响应头字段(2)
res.set({
'X-XSS-Protection': '1; mode=block',
......
});
// 重定向,end 的目的在于表明响应结束,否则请求端会一直等消息体
res.status(302).header('location', 'http://www.duskstar.top').end();
// 重定向简写(1)
res.status(302).location('http://www.duskstar.top').end();
// 重定向简写(2),参数 1 是设置 http 状态码,未设置默认 302
res.redirect(302, 'http://www.duskstar.top');
});
...
注意,Express 是严格遵守 http 状态码语义的。也就是说,你如果想重定向,就要把状态码设成 30X,如果设成 404 那就真的会返回 404 而不会去重定向。
nodemon
最后给大家介绍个实用的小工具吧,开发的时候,每次修改了 Express 代码都要重启服务才能生效。
nodemon 可以帮助我们监控 Nodejs 代码,Node 服务开启后,一旦有代码变动它会自动帮我们重启服务,这将有助于开发者提高开发效率。
🚩 安装及使用:
// 安装,开发依赖
npm i -D nodemon
// 使用,用 nodemon 代替 node 即可
npx nodemon xxx.js
不过默认状态下 nodemon 会监听所有文件哪怕一个空格的变化,这不是我们期望的。
我们可以通过它的配置文件 nodemon.json 来配置,它会监听哪些文件,不会监听哪些…
// nodemon.json
{
// 指定监听所有的 js 和 html 文件
"watch": ["*.js", "*.html"],
// 指定不监听 "package*.json", "nodemon.json" 这些文件
"ignore": ["package*.json", "nodemon.json"]
......
}
更多用法及配置:点击查看
写在最后
One day you’ll leave this world behind. So live a life you will remember ! — Avicii
我是暮星,一枚有志于在前端领域证道的攻城狮。
优质前端内容持续输出中…,欢迎点赞 + 关注 + 收藏。