轻松创建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服务器(5):事件处理程序
Dec 18 NodeJs
NodeJS使用formidable实现文件上传
Oct 27 NodeJs
nodejs的HTML分析利器node-jquery用法浅析
Nov 08 NodeJs
nodejs搭建本地服务器并访问文件的方法
Mar 03 NodeJs
nodejs+express实现文件上传下载管理网站
Mar 15 NodeJs
nodejs 终端打印进度条实例代码
Apr 22 NodeJs
nodejs6下使用koa2框架实例
May 18 NodeJs
手把手教你把nodejs部署到linux上跑出hello world
Jun 19 NodeJs
nodejs实现大文件(在线视频)的读取
Oct 16 NodeJs
nodejs实现解析xml字符串为对象的方法示例
Mar 14 NodeJs
Nodejs让异步变成同步的方法
Mar 02 NodeJs
nodejs简单抓包工具使用详解
Aug 23 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
php空间不支持socket但支持curl时recaptcha的用法
2011/11/07 PHP
php实现读取超大文件的方法
2014/07/28 PHP
phpExcel中文帮助手册之常用功能指南
2014/08/18 PHP
php绘图之在图片上写中文和英文的方法
2015/01/24 PHP
Linux操作系统安装LAMP环境
2015/06/26 PHP
php使用变量动态创建类的对象用法示例
2017/02/06 PHP
php+jQuery ajax实现的实时刷新显示数据功能示例
2019/09/12 PHP
Gambit vs CL BO3 第三场 2.13
2021/03/10 DOTA
基于jquery的兼容各种浏览器的iframe自适应高度的脚本
2010/08/13 Javascript
js点击页面其它地方将某个显示的DIV隐藏
2012/07/12 Javascript
Textarea根据内容自适应高度
2013/10/28 Javascript
Iframe实现跨浏览器自适应高度解决方法
2014/09/02 Javascript
javascript学习笔记之函数定义
2015/06/25 Javascript
javascript中递归函数用法注意点
2015/07/30 Javascript
jQuery表格插件datatables用法详解
2020/11/23 Javascript
基于JavaScript短信验证码如何实现
2016/01/24 Javascript
Angular中$cacheFactory的作用和用法实例详解
2016/08/19 Javascript
微信小程序使用modal组件弹出对话框功能示例
2017/11/29 Javascript
JS实现监控微信小程序的原理
2018/06/15 Javascript
vue的过滤器filter实例详解
2018/09/17 Javascript
vue组件之间通信方式实例总结【8种方式】
2019/02/22 Javascript
vue $mount 和 el的区别说明
2020/09/11 Javascript
针对Vue路由history模式下Nginx后台配置操作
2020/10/22 Javascript
[01:24:51]2014 DOTA2华西杯精英邀请赛 5 25 LGD VS NewBee第二场
2014/05/26 DOTA
Python引用(import)文件夹下的py文件的方法
2014/08/26 Python
python解决网站的反爬虫策略总结
2016/10/26 Python
python解决js文件utf-8编码乱码问题(推荐)
2018/05/02 Python
解决Python3中的中文字符编码的问题
2018/07/18 Python
python set内置函数的具体使用
2019/07/02 Python
详解如何使用CSS3中的结构伪类选择器和伪元素选择器
2020/01/06 HTML / CSS
HTML5之SVG 2D入门13—svg对决canvas及长处和适用场景分析
2013/01/30 HTML / CSS
印度购物网站:TATA CLiQ
2017/11/23 全球购物
阳光体育活动方案
2014/02/16 职场文书
个人工作表现评语
2014/04/30 职场文书
奥巴马就职演讲稿
2014/05/15 职场文书
刑事和解协议书范本
2014/11/19 职场文书