前言
Express一共提供了五个大类的API,每个大类其核心只有几个需要记忆,其它API触类旁通即可(官方文档)。
五大类API
- express.xxx
- app.xxx
- request.xxx
- response.xxx
- router.xxx
一些概念:
子应用:
let app = express() // 主应用
let admin = express() // 另一个应用
app.use('/admin', admin) // admin 作子应用
挂载点:
‘/admin’ 就是admin的挂载点
express.xxx
一共7个API
核心API:
1、exoress.json():这是Express中的内置中间件功能。它根据主体解析器解析带有JSON负载的传入请求。
app.use(express.json());
2、express.static():这是Express中的内置中间件功能。返回将所有主体解析为Buffer的中间件。主要负责解析二进制文件。
app.use(express.json());
3、express.Router():创建一个新的路由对象,可选的options参数指定路由器的行为。
var express = require('express');
var router = express.Router();
/* GET home page. */
router.get('/', function(req, res, next) {
res.render('index', { title: 'Express' });
});
module.exports = router;
app.xxx
一共22个API
核心API:
1、app.set('views' | 'view exgine', xxx):将设置名称分配给值。可以存储所需的任何值,但是可以使用某些名称来配置服务器的行为。这些特殊名称在应用程序设置表中列出。并且app.set()设置必须要在所以app相关操作之前,不然不会有效果。
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', indexRouter);
app.use('/users', usersRouter);
2、app.get('env'):返回名称应用程序app.set()设置的值,其中名称是应用程序设置表中的字符串之一。
app.get('title')
// => undefined
app.set('title', 'My Site')
app.get('title')
// => "My Site"
3、app.get('/xxx, fn'):如果app.get()为传两个参数,则使用指定的回调函数将HTTP GET请求路由到指定的路径。
app.get('/', function (req, res) {
res.send('GET request to homepage')
})
4、app.post / app.put / app.delete...:post、put、delete相关请求的封装。
app.post('/', function (req, res) {
res.send('POST request to homepage')
})
5、app.render():通过回调函数返回视图模板呈现的HTML。它接受一个可选参数,该参数是一个包含视图局部变量的对象。就像res.render()一样,只不过它不能自行将渲染的视图发送给客户端。
app.render('email', function (err, html) {
// ...
})
app.render('email', { name: 'Tobi' }, function (err, html) {
// ...
})
6、app.use():将指定的一个或多个中间件函数安装在指定的路径上:当所请求路径的基数与path匹配时,将执行中间件函数。
app.use([path,] callback [, callback...])
// this middleware will not allow the request to go beyond it
app.use(function (req, res, next) {
res.send('Hello World')
})
// requests will never reach this route
app.get('/', function (req, res) {
res.send('Welcome')
})
requset.xxx
一共有28个API
核心API:
1、req.get('Content-type'):返回指定的HTTP请求标头字段。
req.get('Content-Type')
// => "text/plain"
req.get('content-type')
// => "text/plain"
req.get('Something')
// => undefined
2、req.param('name'):如果参数存在,则返回参数名称的值。
// ?name=tobi
req.param('name')
// => "tobi"
// POST name=tobi
req.param('name')
// => "tobi"
// /user/tobi for /user/:name
req.param('name')
// => "tobi"
3、req.range():参考MDN,表示检测服务器是否支持范围请求,如果支持范围请求则可以使用分片下载,一次请求文档的多个部分,加快下载速度等等。
假如在响应中存在 Accept-Ranges
首部(并且它的值不为 “none”),那么表示该服务器支持范围请求。例如,你可以使用 cURL 发送一个 HEAD
请求来进行检测。
curl -I http://i.imgur.com/z4d4kWk.jpg
HTTP/1.1 200 OK
...
Accept-Ranges: bytes
Content-Length: 146515
在上面的响应中, Accept-Ranges: bytes
表示界定范围的单位是 bytes 。这里 Content-Length
也是有效信息,因为它提供了要检索的图片的完整大小。
如果站点未发送 Accept-Ranges
首部,那么它们有可能不支持范围请求。一些站点会明确将其值设置为 "none",以此来表明不支持。在这种情况下,某些应用的下载管理器会将暂停按钮禁用。
response.xxx
一共24个API
核心API:
1、res.send() / res.sendFile():发送HTTP响应。主体参数可以是Buffer对象,String,Object或Array。
res.send(Buffer.from('whoop'))
res.send({ some: 'json' })
res.send('<p>some html</p>')
res.status(404).send('Sorry, we cannot find that!')
res.status(500).send({ error: 'something blew up' })
2、res.render() / res.download():渲染视图,并将渲染的HTML字符串发送到客户端。
// send the rendered view to the client
res.render('index')
// if a callback is specified, the rendered HTML string has to be sent explicitly
res.render('index', function (err, html) {
res.send(html)
})
// pass a local variable to the view
res.render('user', { name: 'Tobi' }, function (err, html) {
// ...
})
3、res.headersSent:布尔值,指示应用程序是否为响应发送了HTTP标头。
app.get('/', function (req, res) {
console.dir(res.headersSent) // false
res.send('OK')
console.dir(res.headersSent) // true
})
4、res.status():设置响应的HTTP状态。它是Node的response.statusCode的可链接别名。
res.status(403).end()
res.status(400).send('Bad Request')
res.status(404).sendFile('/absolute/path/to/404.png')
5、res.set() / res.get():设置响应头,返回响应头。
res.set('Content-Type', 'text/plain')
res.set({
'Content-Type': 'text/plain',
'Content-Length': '123',
'ETag': '12345'
})
res.get('Content-Type')
// => "text/plain"
6、res.format():如果存在,则对请求对象上的Accept HTTP标头执行内容协商。它根据质量值排序的可接受类型,使用req.accepts()选择请求的处理程序。如果未指定头,则调用第一个回调。如果找不到匹配项,则服务器以406“不可接受”响应,或调用默认回调。
res.format({
'text/plain': function () {
res.send('hey')
},
'text/html': function () {
res.send('<p>hey</p>')
},
'application/json': function () {
res.send({ message: 'hey' })
},
'default': function () {
// log the request and respond with 406
res.status(406).send('Not Acceptable')
}
})
router.xxx
一共5个API
没有特别需要学习的API,因为router就是一个阉割版的app。
var router = express.Router()
router.param('user_id', function (req, res, next, id) {
// sample user, would actually fetch from DB, etc...
req.user = {
id: id,
name: 'TJ'
}
next()
})
router.route('/users/:user_id')
.all(function (req, res, next) {
// runs for all HTTP verbs first
// think of it as route specific middleware!
next()
})
.get(function (req, res, next) {
res.json(req.user)
})
.put(function (req, res, next) {
// just an example of maybe updating the user
req.user.name = req.params.name
// save user ... etc
res.json(req.user)
})
.post(function (req, res, next) {
next(new Error('not implemented'))
})
.delete(function (req, res, next) {
next(new Error('not implemented'))
})
API总结
- express.xxx:内置中间件
- app.xxx:应用设置(如模板配置、中间件、挂载路由)
- req.xxx:操作请求
- res.xxx:操作响应
- router.xxx:操作路由