Express.js 应用-路由定义和不同HTTP请求方式传递参数的接收

 2016年03月11日    2091     声明


一个HTTP服务器就是用来接收来自用户的HTTP请求和响应用户请求的,Express通过路由实现了不同HTTP请求方法的接收,在响应用户请求之前,服务器可能需要根据用户传递的参数不同而已。


  1. Express路由定义与参数接收
  2. 不同HTTP请求方法中的参数接收

1. Express路由定义与参数接收

1.1 Express路由定义

router.all()

在Express中,可以使用router.all()方法定义一个用于所有类型HTTP请求方法的路由:

router.all(path, [callback, ...] callback)

通过router.all()方法定义的路由,可以在所有HTTP请求方法中使用。利用这一特点,在“全局化”匹配指定路径或部分路径或作意匹配时非常有用。在router.all()路由中,可做一些通用的操作(如:验证用户身份等),并可以通过调用netx()方法进行后续路匹配。

如,在以下示例中requireAuthenticationloadUser分别用于验证用户身份和加载用户信息。我们需要在用户所有类型的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请求方法,使用如GETPUTPOST等请求方式小写表示,分别表示为router.get()router.put()router.post()

router.get('/', function(req, res){
  res.send('hello world');
});

定义路由时,可以使用正则表达式。如,要匹配GET /commits/71dbb9cGET /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请求方法中,只有POSTPUTPATCH三种方法存在请求体,在其它请求方法中req.body是一个空对象({})。

POST使用最多的是form表单数据的接收(form表单只能使用GETPOST两种请求方式),而PUTPATCH方法一般用于一些REST标准的API中。

req.body;  // 接收HTTP请求体中的参数


2. 不同HTTP请求方法中的参数接收

接下来我们会使用GETHEADPOSTPUTDELETECONNECTOPTIONSTRACEPATCH9种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标准不尽一致,除HEADCONNECT请求方法外,其它请求方式均支付三种参数接收方式。
  • Express在处理各类HTTP请求时没有严格按HTTP标准执行,在HTTP标准中只有POSTPUTPATCH三种请求方式中存在HTTP请求体(即:body参数),但在Express及其中间件解析时,除HEAD方法外并没有区分body参数
  • 除不被支持的CONNECT方法外,其它所有接收方式均支付URL查询字符串参数路由参数。

在使用Express应用和Express路由及中间件时,建议按HTTP标准进行处理和参数传递。尤其是body参数,在标准中只有POSTPUTPATCH三种方式可以传递body HTTP请求体,除这三种方式外,建议不要使用req.body方法。