轻松创建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 Web应用监听sock文件实例
Feb 18 NodeJs
nodeJs爬虫获取数据简单实现代码
Mar 29 NodeJs
浅谈Nodejs应用主文件index.js
Aug 28 NodeJs
nodejs连接mongodb数据库实现增删改查
Dec 01 NodeJs
使用nodejs下载风景壁纸
Feb 05 NodeJs
基于nodejs 的多页面爬虫实例代码
May 31 NodeJs
nodejs+express搭建多人聊天室步骤
Feb 12 NodeJs
基于Nodejs的Tcp封包和解包的理解
Sep 19 NodeJs
nodejs中方法和模块用法示例
Dec 24 NodeJs
详解nodejs http请求相关总结
Mar 31 NodeJs
NodeJs内存占用过高的排查实战记录
May 10 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开发文件系统实例讲解
2006/10/09 PHP
PHP实现邮件群发的源码
2013/06/18 PHP
PHP连接和操作MySQL数据库基础教程
2014/09/29 PHP
php实现TCP端口检测的方法
2015/04/01 PHP
表单提交错误后返回内容消失问题的解决方法(PHP网站)
2015/10/20 PHP
JavaScript入门教程(5) js Screen屏幕对象
2009/01/31 Javascript
JavaScript Event学习第五章 高级事件注册模型
2010/02/07 Javascript
jqPlot 基于jquery的画图插件
2011/04/26 Javascript
JS加jquery简单实现标签元素的显示或隐藏
2013/09/23 Javascript
Jquery选择器中使用变量实现动态选择例子
2014/07/25 Javascript
浅谈jQuery中replace()方法
2015/05/13 Javascript
js实现继承的5种方式
2015/12/01 Javascript
jQuery easyUI datagrid 增加求和统计行的实现代码
2016/06/01 Javascript
基于JS实现发送短信验证码后的倒计时功能(无视页面刷新,页面关闭不进行倒计时功能)
2016/09/02 Javascript
webpack 1.x升级过程中的踩坑总结大全
2017/08/09 Javascript
深入掌握 react的 setState的工作机制
2017/09/27 Javascript
JavaScript数据结构之单链表和循环链表
2017/11/28 Javascript
ES5新增数组的实现方法
2020/05/12 Javascript
[05:08]2014DOTA2国际邀请赛 Hao专访复仇的胜利很爽
2014/07/15 DOTA
Python中type的构造函数参数含义说明
2015/06/21 Python
Python内建模块struct实例详解
2018/02/02 Python
tensorflow实现简单的卷积神经网络
2018/05/24 Python
python实现指定ip端口扫描方式
2019/12/17 Python
python软件都是免费的吗
2020/06/18 Python
python 下划线的不同用法
2020/10/24 Python
如何利用python生成MD5并去重
2020/12/07 Python
世界最大的票务市场:viagogo
2017/02/16 全球购物
经济学人订阅:The Economist
2018/07/19 全球购物
PHP中如何使用Cookie
2015/10/28 面试题
PHP面试题大全
2015/10/16 面试题
介绍一下HDLC(High-Level Data Link Control)高层数据链路协议
2012/01/21 面试题
4s客服专员岗位职责
2013/12/01 职场文书
远程网络教育毕业生自我鉴定
2014/04/14 职场文书
公司业务员管理制度
2015/08/05 职场文书
2016习总书记系列重要讲话心得体会
2016/01/15 职场文书
python双向链表实例详解
2022/05/25 Python