express 使用 method-override 增加请求类型
一、需求
为了给 express 增加多种类型的请求方法,需要对请求方法进行覆盖。
express 支持的请求方式如下:
要增加请求类型,可以自定义中间件或者使用 method-override 中间件来完成。
二、自己实现一个中间件
自己实现请求类型也是通过增加一个隐藏的标识字段来实现的。
比如在 GET 或者 POST 请求中,增加一个 __method 字段,值为真实的请求类型。
比如下面的表单,发送 SEARCH 类型的请求:
<form action="/" method="post">
<input type="hidden" name="__method" value="search">
<button type="">submit</button>
</form>
中间件的原理就是获取到 method 字段,并且覆盖掉原有的 req.method
下面的中间方法中,需要注意的是:
如果 query 中存在 __method(主要是GET方式的请求),则覆盖。
如果 body 中存在 method (POST方式请求),则覆盖。注意需要判断 body 是否存在,是否是对象,是否有 method 属性。
这种中间件只是演示一下中间件覆写方法的原理
/**
* @name methodOverride
* @description 请求方法重写中间件
*/
function methodOverride(req,res,next){
req.oldMethod = req.method;
// GET 请求 在query中寻找 __method
if(req.query.__method){
req.method = req.query.__method;
}
// POST 请求 在 body 中寻找 __method
if(req.body && typeof req.body === 'object' && '__method' in req.body){
req.method = req.body.__method;
}
next();
}
module.exports = methodOverride;
二、使用 method-override
如果使用 method-override 的话,直接安装中间件,根据文档使用就可以。
https://github.com/expressjs/method-override
安装:
yarn add method-override
method-override 建议,所有的重写方法请求,应当均为 POST
1)通过在 url 中增加 __method=??? 来使用:
如果是直接在 URL 上面手动写上一个 query 参数,则可以直接像下面这样使用:
var express = require('express')
var methodOverride = require('method-override')
var app = express()
// 在 url 中直接加上 ?_method=DELETE
app.use(methodOverride('__method'))
而这样的表单可能如下方式:
<form method="POST" action="/resource?__method=DELETE">
<button type="submit">Delete resource</button>
</form>
2)通过隐藏字段 __method = ??? 的方式:
如果是和上面自定义隐藏表单字段的方式,则需要通过下面这种方式使用:
相比较而言,我觉得这种方式过于麻烦,不过反正官方已经实现掉了。
var bodyParser = require('body-parser')
var express = require('express')
var methodOverride = require('method-override')
var app = express()
// 注意,如果你使用 req.body 来完成,则首先必须调用 body-parser 进行 urlencode 操作
app.use(bodyParser.urlencoded())
app.use(methodOverride(function (req, res) {
if (req.body && typeof req.body === 'object' && '_method' in req.body) {
// look in urlencoded POST bodies and delete it
var method = req.body._method
delete req.body._method
return method
}
}));
此时的表单可能如下:
<form method="POST" action="/resource" enctype="application/x-www-form-urlencoded">
<input type="hidden" name="_method" value="DELETE">
<button type="submit">Delete resource</button>
</form>
3)通过 http 请求头完成覆写
如果做 API ,则可能更加倾向于使用 请求头字段 完成标识。
比如使用这个请求头 X-HTTP-Method-Override:
var express = require('express')
var methodOverride = require('method-override')
var app = express()
// override with the X-HTTP-Method-Override header in the request
app.use(methodOverride('X-HTTP-Method-Override'))
则在请求的时候,只需要设置一下请求头即可:
var xhr = new XMLHttpRequest()
xhr.onload = onload
xhr.open('post', '/resource', true)
xhr.setRequestHeader('X-HTTP-Method-Override', 'DELETE')
xhr.send()
function onload () {
alert('got response: ' + this.responseText)
}