一个HTTP
服务器就是用来接收来自用户的HTTP请求和响应用户请求的,Express
通过路由
实现了不同HTTP请求方法的接收,在响应用户请求之前,服务器可能需要根据用户传递的参数不同而已。
1. Express路由定义与参数接收
1.1 Express路由定义
router.all()
在Express中,可以使用router.all()
方法定义一个用于所有类型HTTP请求方法的路由:
router.all(path, [callback, ...] callback)
通过router.all()
方法定义的路由,可以在所有HTTP请求方法中使用。利用这一特点,在“全局化”匹配指定路径或部分路径或作意匹配时非常有用。在router.all()
路由中,可做一些通用的操作(如:验证用户身份等),并可以通过调用netx()
方法进行后续路匹配。
如,在以下示例中requireAuthentication
和loadUser
分别用于验证用户身份和加载用户信息。我们需要在用户所有类型的HTTP请求和所有的请求路径中进行这两项操作:
router.all('*', requireAuthentication, loadUser);
等价于:
router.all('*', requireAuthentication) router.all('*', loadUser);
有时候只需要在部分URL中做一些处理,如在/api
开头的路由中进行匹配和处理:
router.all('/api/*', requireAuthentication);
router.METHOD()
Express中针对某一种HTTP请求方法设置路由,使用router.METHOD()
方法:
router.METHOD(path, [callback, ...] callback)
router.METHOD()
设置某一种HTTP请求方法的路由,METHOD
表示HTTP请求方法,使用如GET
、PUT
、POST
等请求方式小写表示,分别表示为router.get()
、router.put()
、 router.post()
:
router.get('/', function(req, res){ res.send('hello world'); });
定义路由时,可以使用正则表达式。如,要匹配GET /commits/71dbb9c
和GET /commits/71dbb9c..4c084f9
的路由形式,匹配规则如下:
router.get(/^\/commits\/(\w+)(?:\.\.(\w+))?$/, function(req, res){ var from = req.params[0]; var to = req.params[1] || 'HEAD'; res.send('commit range ' + from + '..' + to); });
1.2 参数接收
在Express.js
中,接收用户参数有三种形式:路由(路径)参数、URL 查询字符串参数、body(HTTP请求体)参数。
路由(路径)参数
设置如下一下路由:
router.get('/user/:id', function(req, res, next){ // 接收路由参数 req.params.id });
路由参数通过req.params
取值。在上面示例中,/user/:id
路由中的:id
参数是一个变量,可以通过req.params.id
接收这个变量的值。
URL 查询字符串参数
URL 查询字符串参数
是在指在URL中传递的参数,这些参数不需要在路由中设置,接收查询字符串参数使用req.query
对象。当我们发送一个GET /user?id=1&name=myName
请求时,接收这个对象使用如下方法:
console.log(req.query); // {id:'1', name:'myName'}
body(HTTP请求体)参数
body
参数通过req.body
(需要body-parser
模块处理)对象接收,body
参数是指HTTP请求体中的参灵敏。在HTTP请求方法中,只有POST
、PUT
、PATCH
三种方法存在请求体,在其它请求方法中req.body
是一个空对象({}
)。
POST
使用最多的是form
表单数据的接收(form
表单只能使用GET
、POST
两种请求方式),而PUT
和PATCH
方法一般用于一些REST
标准的API中。
req.body; // 接收HTTP请求体中的参数
2. 不同HTTP请求方法中的参数接收
接下来我们会使用GET
、HEAD
、 POST
、PUT
、DELETE
、 CONNECT
、OPTIONS
、TRACE
、PATCH
9种HTTP请求方法来访问Express.js应用,目的是测试Express.js
对各类HTTP请求的支付情况和各种HTTP请求方式的参数接收情况。
2.1 定义路由和客户端代码
使用request
来实现一个HTTP客户端,我们会在这个客户端中分别添加:路由参数
、URL查询字符串参数
和body 参数
,通过变更options.method
参数分别实现了不同方式的HTTP请求:
var request = require('request'); /** * 请求的URL中包含一个query参数和一个params参数 * 请求方法分别使用:'GET'|'HEAD'|'POST'|'PUT'|'DELETE'|'CONNECT'|'OPTIONS'|'TRACE'|'PATCH' */ var options ={ uri: 'http://127.0.0.1:3000/node?q='+encodeURIComponent('IT笔录'), method: 'GET', headers: { 'Content-type': 'application/x-www-form-urlencoded' }, body: 'form=itbilu.com' // 一个body参数 } request(options, callback) function callback(error, response, body) { if (!error && response.statusCode == 200) { var info = JSON.parse(body); console.log(info); } }
在Express
应用中,定义如下一个路由,客户所有的类型的HTTP请求都会发送到这个路由中。这个路由使用router.all()
/* 一个处理所有请求的中间件 */ router.all('/:path', function(req, res, next){ // 客户端请求使用的HTTP方法 var method = req.method; // URL 查询字符串参数 var query = req.query; // body(HTTP请求体)参数 var body = req.body; // 路由(路径)参数 var params = req.params; console.log(method); console.log('query:', query); console.log('body:', body); console.log('params:', params); next(); });
2.2 HTTP请求的接收
下面是HTTP客户端发送不同类型HTTP请求后,Express应用对各种请求的方式的参数接收情况:
GET
请求
GET query:{ q: 'IT笔录' } body:{ from: 'itbilu.com' } params:{ path: 'node' } GET /node?q=IT%E7%AC%94%E5%BD%95
HEAD
请求
HEAD query:{ q: 'IT笔录' } body:{} params:{ path: 'node' } HEAD /node?q=IT%E7%AC%94%E5%BD%95
HEAD
请求时,客户端不能包含body
参数,否则会报错。
POST
请求
POST query:{ q: 'IT笔录' } body:{ from: 'itbilu.com' } params:{ path: 'node' } POST /node?q=IT%E7%AC%94%E5%BD%95
PUT
请求
PUT query:{ q: 'IT笔录' } body:{ from: 'itbilu.com' } params:{ path: 'node' } PUT /node?q=IT%E7%AC%94%E5%BD%95
DELETE
请求
DELETE query:{ q: 'IT笔录' } body:{ from: 'itbilu.com' } params:{ path: 'node' } DELETE /node?q=IT%E7%AC%94%E5%BD%95
CONNECT
请求
// 无返回,request模块不支付
OPTIONS
请求
OPTIONS query:{ q: 'IT笔录' } body: { from: 'itbilu.com' } params:{ path: 'node' } OPTIONS /node?q=IT%E7%AC%94%E5%BD%95
TRACE
请求
TRACE query:{ q: 'IT笔录' } body:{ from: 'itbilu.com' } params:{ path: 'node' } TRACE /node?q=IT%E7%AC%94%E5%BD%95
PATCH
请求
PATCH query:{ q: 'IT笔录' } body:{ from: 'itbilu.com' } params:{ path: 'node' } PATCH /node?q=IT%E7%AC%94%E5%BD%95
2.3 总结
经过上面的测试我们可以得出以下结论:
Experss
与HTTP标准不尽一致,除HEAD
、CONNECT
请求方法外,其它请求方式均支付三种参数接收方式。Express
在处理各类HTTP请求时没有严格按HTTP标准执行,在HTTP
标准中只有POST
、PUT
、PATCH
三种请求方式中存在HTTP请求体(即:body
参数),但在Express
及其中间件解析时,除HEAD
方法外并没有区分body
参数- 除不被支持的
CONNECT
方法外,其它所有接收方式均支付URL查询字符串参数
和路由参数。
在使用Express应用和Express路由及中间件时,建议按HTTP标准进行处理和参数传递。尤其是body
参数,在标准中只有POST
、PUT
、PATCH
三种方式可以传递body HTTP请求体
,除这三种方式外,建议不要使用req.body
方法。