本文从安装、用法、常用 API 等方面简单介绍了 Express 的用法。
一、Express
简介
1、Express 是什么?
基于
Node
平台开发的Web
开发框架提供一系列强大的特性,帮助创建各种 Web和移动设备应用
是 NodeJS 的一个模块
2、为什么使用 Express
- 为了基于 NodeJS 开发 web 应用程序更高效
二、安装与使用
1、安装
1 | # 新建 my-app 文件夹 |
2、基本使用
根目录下新建 index.js
文件
1 | const express = require('express'); |
根目录下运行 node index.js
,即可看到控制台打印输出。说明服务已经启动
3、路由
基本路由
基本使用方式:
1 | // Get 请求 |
或者使用 app.route() 的方式
1 | app.route('/') |
特殊路由:app.all([path,] callback)
- 不写 path 参数,默认是根路径
- 请求路径(
pathname
)必须要全等于path
,才会执行callback
; - 任意请求方式都会执行
callback
函数
1 | app.all('/book', (req, res) => { |
app.use([path,] callback)
- 不写 path 参数,默认是根路径
- 只要请求路径(
pathname
)第一段为path
,就会执行callback
; - 任意请求方式都会执行
callback
函数
1 | app.use('/book', (req, res) => { |
4、路由拆分:express.Router([options])
options
中的参数:
属性 | 描述 | 默认值 |
---|---|---|
caseSensitive | 启用区分大小写。 | 默认情况下禁用,将“/ Foo”和“/ foo”视为相同。 |
mergeParams | 保留req.params父路由器的值。如果父级和子级具有冲突的参数名称,则子级的值优先。 | false |
strict | 启用严格路由。 | 默认情况下禁用,“/ foo”和“/ foo /”由路由器处理相同。 |
将所有的路由都写在 index.js
文件中,不易维护而且也不安全,所以我们可以把不同路径下的路由进行拆分,分别放在不同文件下,易于维护。这个时候就会用到 express.Router()
;
与
app
类似,也可以使用route()
、all()
、use()
等方法
编写路由文件 order.js
1 | const express = require('express'); |
即可在 index.js 中使用
1 |
|
访问 http://localhost: 3000/order/list
或者其他 order
文件中的路径即可获取到对应返回结果
5、访问静态资源
api: app.use([pathname,] express.static(root,[options]))
pathname
: 访问路径root
: 静态资源文件夹路径options
: 其他配置项,可参考这里
此时假如 public
文件是静态文件存放目录,文件夹下有 a.png
的图片文件
1 | app.use('/public', express.static(path.join(__dirname, 'public'))); |
则此时访问 http://localhost: 3000/public/a.png
,可以看到图片正常显示。
6、中间件的使用
app.use([path, ] (req, res, next) => { ...; next() })
path
参数可写可不写,不写则默认为根路径,所有访问路径均可使用;- 比一般回调函数多一个
next
参数,必须执行,否则不会继续向下执行。
三、常用 API
1、Application
app.listen([port [,host [,backlog]]] [,callback])
启动服务,监听端口地址
app.METHOD(path,callback [,callback ...])
路由请求方式:
METHOD
为各种请求方式path
:请求路径callback
:中间件及回调函数,可包含多个,出最后一个外,其他的必须在最后执行next()
,否则不会再继续向下执行
app.path()
返回应用程序的规范路径,一个字符串。
1 | var app = express(); |
app.set(name, value) / app.get(name)
app.set(name, value)
:为name
属性设置value
,存储到服务器中app.get(name)
:获取name
属性对应的value
错误处理中间件的使用
1 | app.use((err, req, res, next) => { |
2、Request
req.params
获取请求路径中的 param
例如请求路径为:http://localhost:3000/news/2019/10
1 | app.get('/news/:year/:month', (req, res) => { |
req.query
获取 Get
请求路径中传递的查询参数
例如 Get
请求为:http://localhost:3000?name=zgd
1 | app.get('/', (req, resp) => { |
req.body
获取 Post
请求中能够传递的查询参数
例如 Post
请求为:curl -d "name=zgd" http://localhost:3000
1 | app.use(express.json()) // for parsing application/json |
req 获取路径
- req.baseUrl:安装路由器实例的URL路径,不包含请求参数
- req.path: 当前请求路径,不包含请求参数
- req.originalUrl:院士路径,即全路径,包含请求参数
- req.url:当前请求路径,包含请求参数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15app.get('/book/list', (req, res) => {
res.write(req.baseUrl); // ''
res.write(req.path); // '/book/list'
res.write(req.originalUrl); // '/book/list'
});
app.use('/book', book);
// book.js
router.get('/list', (req, res) => {
res.write(req.baseUrl); // '/book'
res.write(req.path); // '/list'
res.write(req.originalUrl); // '/book/list'
})
其他属性
属性 | 描述 | 例子 |
---|---|---|
req.baseUrl | 安装路由器实例的URL路径。 | 用法查看这里 |
req.path | 当前请求路径 | 用法查看这里 |
req.originalUrl | 原始 URL 请求路径。后面没有跟请求参数时,相当于是 baseUrl + path;路径后面跟了请求参数,则请求参数也包含在内 | / GET /search?q=something / console.dir(req.originalUrl); // => ‘/search?q=something’ |
req.cookies | 此属性是包含请求发送的cookie的对象。如果请求不包含cookie,则默认为{}。 | console.dir(req.cookies.name) |
req.signedCookies | 同 req.cookies | 如果cookie已签名,必须使用这个,而不能使用 req.cookies |
req.fresh | 指示请求是否“新鲜”。它是相反的req.stale。 | 用法查看这里 |
req.stale | 指示请求是否“陈旧”,并且与之相反req.fresh。 | 用法查看这里 |
req.hostname | 包含从HostHTTP标头派生的主机名。 | / Host: “example.com:3000” / console.dir(req.hostname); // => ‘example.com’ |
req.ip | 包含请求的远程IP地址。 | console.dir(req.ip); // => ‘127.0.0.1’ |
req.method | 包含对应于该请求的HTTP方法的字符串: GET,POST,PUT,等。 | - |
req.protocol | 包含请求协议字符串:http或者(对于TLS请求)https。 | console.dir(req.protocol); // => ‘http’ |
req.route | 包含当前匹配的路由,一个对象。 | 用法查看这里 |
req.secure | 一个布尔属性,如果建立了TLS连接,则该属性为true。 | 相当于:console.dir(req.protocol === ‘https’); // => true |
req.subdomains | 请求的域名中的一组子域。 | / Host: “tobi.ferrets.example.com” / console.dir(req.subdomains); // => [‘ferrets’, ‘tobi’] |
req.xhr | 一个布尔属性,true如果请求的X-Requested-With头字段是“XMLHttpRequest”,则表示该请求是由客户端库(如jQuery)发出的。 | console.dir(req.xhr); // => true |
3、Response
res.end([data] [,encoding])
结束响应过程。
1 | res.end() |
res.send([body])
与 res.end()
的区别:
- 参数
body
可以是String
、Buffer
,也可以是Array
、Object
- 会自动添加响应头:”Content-Type: text/html; charset=utf-8”
1 | res.send(Buffer.from('whoop')) |
res.sendFile(path [,options] [,fn])
在指定时间发送文件到客户端。Content-Type
会根据文件的扩展名设置响应 HTTP
响应头字段。除非在 options
对象中设置了该选项,否则 path
必须是该文件的绝对路径。
1 | app.get('/file/:name', function (req, res, next) { |
res.sendStatus(statusCode)
设置响应状态码并结束响应
1 | res.sendStatus(200) // equivalent to res.status(200).send('OK') |
res.status
设置响应状态码
1 | res.status(200).send('OK') |
res.set(field [,value])
将响应的 HTTP
请求头 field
设置为 value
。要一次设置多个字段,请传递一个对象作为参数。
1 | res.set('Content-Type', 'text/plain') |
res.get(field)
返回由指定的HTTP响应头field。该匹配不区分大小写。1
2res.get('Content-Type')
// => "text/plain"
res.redirect([status,] path)
重定向到指定的 URL path
,具有指定的status与HTTP状态代码对应的正整数。如果未指定,则status默认为”302”。
1 | res.redirect('/foo/bar') |
res.json([body])
用法同 res.send()
;
res.append(field [,value])
将指定的内容追加 value
到 HTTP
响应头 field
。如果尚未设置标头,则会创建具有指定值的标头。所述 value
参数可以是字符串或数组。
注意:调用res.set()after res.append()将重置先前设置的标头值。
1 | res.append('Link', ['<http://localhost/>', '<http://localhost:3000/>']) |
res.cookie(name,value [, options])
设置 cookie
中的 name
属性为 value
1 | res.cookie('name', 'tobi', { domain: '.example.com', path: '/admin', secure: true }) |
res.clearCookie(name [,options])
清除 cookie
中对应的 name
属性
1 | res.cookie('name', 'tobi', { path: '/admin' }) |
Router
与 app 中使用 路由的方式类似:
router.Method(path, callback)
router.use()
router.all()
router.route()