Express中method-override模块详解(一): 使用

来源:互联网 发布:德州扑克辅助软件 编辑:程序博客网 时间:2024/06/10 22:48

*注意,如果你在使用Node.js实战(Mike Catelon)这本书,一定注意下书中所用的connect和experss版本。总的来说,这个两个版本都太老了,学习时最好使用最新的版本。因为很多开源框架都是基于新版本而来,你会发现书中的api在很多实际项目已经不能用了。

在本博文中,我使用的express版本为4。method-override版本为2.2.0.


1. 为什么需要method-override

这个需求主要来自前端的form。比如我们在后端提供一个针对HTTP PUT的API, 前端的数据提交时,我们自然希望FORM能够产生一个PUT请求。然而,浏览器的FORM只能GET或者POST。怎么办? 改变后端的API吗?如果这个API是别的服务商提供,我们无权更改呢?这时,我们就需要method-override来帮助我们。

先看一个例子吧 。

var express = require('express'),bodyParser = require('body-parser');function edit (req,res,next) {if(req.method !== 'GET') {return next();}res.setHeader('Content-Type','text/html');res.write('<form method="put">');res.write('<input type="text" name=user[name] value="Tobi"/>');res.write('<input type="submit" value="Update"/>')res.write('</form>');res.end();}function update(req,res,next) {if(req.method !== 'PUT') return next();res.end('update ' + req.body.user.name);}var app = express();app.use(bodyParser()).use(edit).use(update).listen(3000,function(){console.log('start on port 3000');});
访问http://localhost:3000, 点击Update。 什么也没有发生,因为浏览器将PUT 转换成了GET请求。 怎么办?这时我们就需要用到method-override了


2. 怎么使用method-override

2.1 使用隐藏控件

从上面的例子可以看到,由于在FORM中我们只能发送GET或者POST请求,限制了我们使用其他谓词比如PUT,DELETE等,因此我们需要同过method-override将GET或者POST改成其他谓词PUT,DELETE等。

针对上面的例子,介绍一种常规的处理方法。可以在FORM中加入一个名为_method(别的名字也可以)的隐藏输入控件,让这个控件承载我们实际需要的谓词。然后在服务器端用这个控件的谓词进行方法改写。

代码如下:

var express = require('express'),bodyParser = require('body-parser'),methodOverride = require('method-override');function edit (req,res,next) {if(req.method !== 'GET') {return next();}res.setHeader('Content-Type','text/html');res.write('<form method="post">');res.write('<input type="hidden" name="post_to_put" value="put"/>');res.write('<input type="text" name=user[name] value="Tobi"/>');res.write('<input type="submit" value="Update"/>')res.write('</form>');res.end();}function update(req,res,next) {if(req.method !== 'PUT') return next();res.end('update ' + req.body.user.name);}var app = express();app.use(bodyParser()).use(methodOverride(function(req,res){if(req.body && typeof req.body === 'object' && 'post_to_put' in req.body){var method = req.body.post_to_put;delete req.body.post_to_put;return method.toUpperCase();}}))dai.use(edit).use(update).listen(3000,function(){console.log('start on port 3000');});

分析代码,我们看到,FORM提交还是使用POST, 不过我们在FORM中增加了一个隐藏输入,名为POST_TO_PUT,值为PUT。然后在服务器端,我们提供了自定义的改写规则:

1 从request中获取body数据(因此body-parser需要在此前使用),BODY数据里面包含着POST_TO_PUT

2 从body数据中拿到名为POST_TO_PUT的值, 这个值就是我们提供的实际谓词,这里是PUT

3 从body数据中删除POST_TO_PUT属性 (后续使用body数据,就无需考虑这个POST_TO_PUT属性了,它已完成了使命)

4  返回POST_TO_PUT属性值得大写格式

好了,跑一下代码,再次访问http://localhost:3000,提交数据。这次,服务器终于正确返回值了。点击这里,在线运行程序

2.2 使用查询更改

通过2.1介绍的方法,我们可以使用一个非常规则的RESTful API从而达到方法改写的目的。然而这个方式需要在前端引入冗余代码(前端需要编写专门为方法改写而增加的影藏控件)。现在,介绍另一种方法,同过查询URL改写。

1. 首先我们需要为method-override提供一个key以便用得到改写的方法。

app.use(methodOverride('_method')

这里我们提供的键值是_method。当然也可以是其他字符串,但是这个字符串不能以 X- 开始。

2.修改前端代码

<form method="post" action='?_method=PUT'>
这样就好了。点击这里,在线运行程序


接下来,我们要深入method-override源码,仔细探究其中的奥秘

0 0
原创粉丝点击