轻松创建nodejs服务器(10):处理POST请求


Posted in NodeJs onDecember 18, 2014

目前为止,我们做的服务器没有实际的用处,接下来我们开始实现一些实际有用的功能。

我们要做的是:用户选择一个文件,上传该文件,然后在浏览器中看到上传的文件。

首先我们需要一个文本区(textarea)供用户输入内容,然后通过POST请求提交给服务器。

我们在start事件处理器里添加代码,requestHandlers.js修改如下:

function start(response) {

 console.log("Request handler 'start' was called.");

 var body = '<html>'+ '<head>'+

    '<meta http-equiv="Content-Type" content="text/html; '+

    'charset=UTF-8" />'+

    '</head>'+

    '<body>'+

    '<form action="/upload" method="post">'+

    '<textarea name="text" rows="20" cols="60"></textarea>'+

    '<input type="submit" value="Submit text" />'+

    '</form>'+

    '</body>'+

    '</html>';

 response.writeHead(200, {"Content-Type": "text/html"});

 response.write(body);

 response.end();

}

function upload(response) {

 console.log("Request handler 'upload' was called.");

 response.writeHead(200, {"Content-Type": "text/plain"});

 response.write("Hello Upload");

 response.end();

}

exports.start = start;

exports.upload = upload;

通过在浏览器中访问http://localhost:8888/start就可以看到效果了。

接下来我们要实现当用户提交表单时,触发/upload请求处理程序处理POST请求。

为了使整个过程非阻塞,Node.js会将POST数据拆分成很多小的数据块,然后通过触发特定的事件,将这些小数据块传递给回调函数。这里的特定的事件有data事件(表示新的小数据块到达了)以及end事件(表示所有的数据都已经接收完毕)。

我们通过在request对象上注册监听器(listener) 来实现。这里的 request对象是每次接收到HTTP请求时候,都会把该对象传递给onRequest回调函数。

我们把代码放在服务器里,server.js修改如下:

var http = require("http");

var url = require("url");

function start(route, handle) {

 function onRequest(request, response) {

  var postData = "";

  var pathname = url.parse(request.url).pathname;

  console.log("Request for " + pathname + " received.");

  request.setEncoding("utf8");

  request.addListener("data", function(postDataChunk) {

   postData += postDataChunk;

   console.log("Received POST data chunk '"+ postDataChunk + "'.");

  });

  request.addListener("end", function() {

   route(handle, pathname, response, postData);

  });

 }

 http.createServer(onRequest).listen(8888);

 console.log("Server has started.");

}

exports.start = start;

上述代码做了三件事情: 首先,我们设置了接收数据的编码格式为UTF-8,然后注册了“data”事件的监听器,用于收集每次接收到的新数据块,并将其赋值给postData 变量,最后,我们将请求路由的调用移到end事件处理程序中,以确保它只会当所有数据接收完毕后才触发,并且只触发一次。我们同时还把POST数据传递给请求路由,因为这些数据,请求处理程序会用到。

接下来在/upload页面,展示用户输入的内

我们来改一下 router.js:

function route(handle, pathname, response, postData) {

 console.log("About to route a request for " + pathname);

 if (typeof handle[pathname] === 'function') {

  handle[pathname](response, postData);

 } else {

  console.log("No request handler found for " + pathname);

  response.writeHead(404, {"Content-Type": "text/plain"});

  response.write("404 Not found");

  response.end();

 }

}

exports.route = route;

然后,在requestHandlers.js中,我们将数据包含在对upload请求的响应中:
function start(response, postData) {

 console.log("Request handler 'start' was called.");

 var body = '<html>'+

    '<head>'+

    '<meta http-equiv="Content-Type" content="text/html; '+

    'charset=UTF-8" />'+

    '</head>'+

    '<body>'+

    '<form action="/upload" method="post">'+

    '<textarea name="text" rows="20" cols="60"></textarea>'+

    '<input type="submit" value="Submit text" />'+

    '</form>'+

    '</body>'+

    '</html>';

 response.writeHead(200, {"Content-Type": "text/html"});

 response.write(body);

 response.end();

}

function upload(response, postData) {

 console.log("Request handler 'upload' was called.");

 response.writeHead(200, {"Content-Type": "text/plain"});

 response.write("You've sent: " + postData);

 response.end();

}

exports.start = start;

exports.upload = upload;

我们最后要做的是: 当前我们是把请求的整个消息体传递给了请求路由和请求处理程序。我们应该只把POST数据中,我们感兴趣的部分传递给请求路由和请求处理程序。在我们这个例子中,我们感兴趣的其实只是text字段。

我们可以使用此前介绍过的querystring模块来实现:

var querystring = require("querystring");

function start(response, postData) {

 console.log("Request handler 'start' was called.");

 var body = '<html>'+

    '<head>'+

    '<meta http-equiv="Content-Type" content="text/html; '+

    'charset=UTF-8" />'+

    '</head>'+

    '<body>'+

    '<form action="/upload" method="post">'+

    '<textarea name="text" rows="20" cols="60"></textarea>'+

    '<input type="submit" value="Submit text" />'+

    '</form>'+

    '</body>'+

    '</html>';

 response.writeHead(200, {"Content-Type": "text/html"});

 response.write(body);

 response.end();

}

function upload(response, postData) {

 console.log("Request handler 'upload' was called.");

 response.writeHead(200, {"Content-Type": "text/plain"});

 response.write("You've sent the text: "+ querystring.parse(postData).text);

 response.end();

}

exports.start = start;

exports.upload = upload;

好了,以上就是关于处理POST数据的全部内容。

下一节,我们将实现图片上传的功能。

NodeJs 相关文章推荐
nodejs npm包管理的配置方法及常用命令介绍
Jun 05 NodeJs
使用NodeJs 开发微信公众号(三)微信事件交互实例
Mar 02 NodeJs
NodeJS中的MongoDB快速入门详细教程
Nov 11 NodeJs
使用nodejs下载风景壁纸
Feb 05 NodeJs
NodeJS配置HTTPS服务实例分享
Feb 19 NodeJs
nodeJS实现简单网页爬虫功能的实例(分享)
Jun 08 NodeJs
NodeJS实现视频转码的示例代码
Nov 18 NodeJs
Nodejs连接mysql并实现增、删、改、查操作的方法详解
Jan 04 NodeJs
nodejs 日志模块winston的使用方法
May 02 NodeJs
nodejs的安装使用与npm的介绍
Sep 11 NodeJs
如何利用nodejs实现命令行游戏
Nov 24 NodeJs
windows如何把已安装的nodejs高版本降级为低版本(图文教程)
Dec 14 NodeJs
轻松创建nodejs服务器(7):阻塞操作的实现
Dec 18 #NodeJs
轻松创建nodejs服务器(8):非阻塞是如何实现的
Dec 18 #NodeJs
轻松创建nodejs服务器(9):实现非阻塞操作
Dec 18 #NodeJs
轻松创建nodejs服务器(6):作出响应
Dec 18 #NodeJs
轻松创建nodejs服务器(5):事件处理程序
Dec 18 #NodeJs
轻松创建nodejs服务器(4):路由
Dec 18 #NodeJs
轻松创建nodejs服务器(3):代码模块化
Dec 18 #NodeJs
You might like
PHPMailer安装方法及简单实例
2008/11/25 PHP
php URL跳转代码 减少外链
2011/06/25 PHP
php方法调用模式与函数调用模式简例
2011/09/20 PHP
php+mysqli批量查询多张表数据的方法
2015/01/29 PHP
PHP程序员的技术成长规划
2016/03/25 PHP
Thinkphp3.2.3分页使用实例解析
2016/07/28 PHP
PHP简单实现合并2个数字键数组值的方法
2017/05/30 PHP
PHP检查端口是否可以被绑定的方法示例
2018/08/09 PHP
javascript判断iphone/android手机横竖屏模式的函数
2011/12/20 Javascript
AngularJS入门知识之MVW类框架的编程思想探讨
2014/12/08 Javascript
javascript实现根据时间段显示问候语的方法
2015/06/18 Javascript
Knockoutjs 学习系列(二)花式捆绑
2016/06/07 Javascript
jQuery和hwSlider实现内容响应式可触控滑动切换效果附源码下载(二)
2016/06/22 Javascript
JavaScript基于Dom操作实现查找、修改HTML元素的内容及属性的方法
2017/01/20 Javascript
axios发送post请求springMVC接收不到参数的解决方法
2018/03/05 Javascript
微信小程序自定义组件实现tabs选项卡功能
2018/07/14 Javascript
React组件对子组件children进行加强的方法
2019/06/23 Javascript
Cpy和Python的效率对比
2015/03/20 Python
Python3.6连接Oracle数据库的方法详解
2018/05/18 Python
使用python 3实现发送邮件功能
2018/06/15 Python
Python利用heapq实现一个优先级队列的方法
2019/02/03 Python
详解Python3 对象组合zip()和回退方式*zip
2019/05/15 Python
django解决订单并发问题【推荐】
2019/07/31 Python
Pandas 缺失数据处理的实现
2019/11/04 Python
python bluetooth蓝牙信息获取蓝牙设备类型的方法
2019/11/29 Python
Pytorch转tflite方式
2020/05/25 Python
Sisley法国希思黎中国官网:享誉全球的奢华植物美容品牌
2019/06/30 全球购物
法国足球商店:Footcenter
2019/07/06 全球购物
十八届三中全会个人学习材料
2014/02/13 职场文书
全国税务系统先进集体事迹材料
2014/05/19 职场文书
物理分数没达标检讨书
2014/09/13 职场文书
区政府领导班子个人对照检查材料
2014/09/25 职场文书
委托书的样本
2015/01/28 职场文书
汉语拼音教学反思
2016/02/22 职场文书
初三语文教学反思
2016/03/03 职场文书
golang中字符串MD5生成方式总结
2021/07/04 Golang