轻松创建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 相关文章推荐
使用forever管理nodejs应用教程
Jun 03 NodeJs
nodejs URL模块操作URL相关方法介绍
Mar 03 NodeJs
Nodejs中session的简单使用及通过session实现身份验证的方法
Feb 04 NodeJs
Nodejs下用submit提交表单提示cannot post错误的解决方法
Nov 21 NodeJs
nodejs和php实现图片访问实时处理
Jan 05 NodeJs
nodejs搭建本地服务器并访问文件的方法
Mar 03 NodeJs
深入浅析Nodejs的Http模块
Jun 20 NodeJs
理解nodejs的stream和pipe机制的原理和实现
Aug 12 NodeJs
nodejs爬虫初试superagent和cheerio
Mar 05 NodeJs
Nodejs实现多文件夹文件同步
Oct 17 NodeJs
NodeJs之word文件生成与解析的实现代码
Apr 01 NodeJs
NodeJS实现一个聊天室功能
Nov 25 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
c#中的实现php中的preg_replace
2009/12/21 PHP
php下使用iconv需要注意的问题
2010/11/20 PHP
对象失去焦点时自己动提交数据的实现代码
2012/11/06 PHP
ThinkPHP结合ajax、Mysql实现的客户端通信功能代码示例
2014/06/23 PHP
php绘制一条直线的方法
2015/01/24 PHP
PHP信号量基本用法实例详解
2016/02/12 PHP
ThinkPHP框架表单验证操作方法
2017/07/19 PHP
JavaScript开发时的五个注意事项
2007/12/08 Javascript
利用js的Node遍历找到repeater的一个字段实例介绍
2013/04/25 Javascript
jQuery实现简单的间隔向上滚动效果
2015/03/09 Javascript
纯js代码制作的网页时钟特效【附实例】
2016/03/30 Javascript
详解vue-cli 脚手架项目-package.json
2017/07/04 Javascript
详解Vue微信公众号开发踩坑全记录
2017/08/21 Javascript
详解.vue文件中style标签的几个标识符
2018/07/17 Javascript
详解使用jest对vue项目进行单元测试
2018/09/07 Javascript
vue实现文字横向无缝走马灯组件效果的实例代码
2019/04/09 Javascript
vue路由的配置和页面切换详解
2020/09/09 Javascript
Perl中著名的Schwartzian转换问题解决实现
2015/06/02 Python
python简单线程和协程学习心得(分享)
2017/06/14 Python
python实现学生信息管理系统
2020/04/05 Python
如何用Python合并lmdb文件
2018/07/02 Python
详解Python中的内建函数,可迭代对象,迭代器
2019/04/29 Python
Django如何简单快速实现PUT、DELETE方法
2019/07/24 Python
浅谈pytorch中torch.max和F.softmax函数的维度解释
2020/06/28 Python
Python Tricks 使用 pywinrm 远程控制 Windows 主机的方法
2020/07/21 Python
整理HTML5中表单的常用属性及新属性
2016/02/19 HTML / CSS
The Hut德国站点:时装、家居用品、美容等
2016/09/23 全球购物
SQL Server的固定数据库角色都有哪些?对应的服务器权限有哪些?
2013/05/18 面试题
个人充满哲理的自我评价
2014/02/20 职场文书
大学应届生的自我评价
2014/03/06 职场文书
学生会宣传部部长竞选演讲稿
2014/04/25 职场文书
3分钟英语演讲稿
2014/04/29 职场文书
日语专业毕业生自荐书
2014/06/18 职场文书
大学生就业指导课心得体会
2016/01/15 职场文书
使用Oracle命令进行数据库备份与还原
2021/12/06 Oracle
详解SQL报错盲注
2022/07/23 SQL Server