轻松创建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中的非阻塞方法介绍
Jun 05 NodeJs
Nodejs进程管理模块forever详解
Jun 01 NodeJs
Nodejs极简入门教程(一):模块机制
Oct 25 NodeJs
nodejs加密Crypto的实例代码
Jul 07 NodeJs
nodejs基础知识
Feb 03 NodeJs
Nodejs 和Session 原理及实战技巧小结
Aug 25 NodeJs
nodejs socket服务端和客户端简单通信功能
Sep 14 NodeJs
nodeJS服务器的创建和重新启动的实现方法
May 12 NodeJs
nodejs实现套接字服务功能详解
Jun 21 NodeJs
nodejs高大上的部署方式(PM2)
Sep 11 NodeJs
详解nodejs 配置文件处理方案
Jan 02 NodeJs
nodejs环境使用Typeorm连接查询Oracle数据
Dec 05 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 图像尺寸调整代码
2010/05/26 PHP
第4章 数据处理-php字符串的处理-郑阿奇(续)
2011/07/04 PHP
php获取301跳转URL简单实例
2013/12/16 PHP
Codeigniter通过SimpleXML将xml转换成对象的方法
2015/03/19 PHP
PHP 数据结构队列(SplQueue)和优先队列(SplPriorityQueue)简单使用实例
2015/05/12 PHP
JavaScript 中的事件教程
2007/04/05 Javascript
javascript instanceof 与typeof使用说明
2010/01/11 Javascript
JavaScript常用对象的方法和属性小结
2012/01/24 Javascript
javascript模块化是什么及其优缺点介绍
2013/09/02 Javascript
js变量、作用域及内存详解
2014/09/23 Javascript
不用一句js代码初始化组件
2016/01/27 Javascript
js基本算法:冒泡排序,二分查找的简单实例
2016/10/08 Javascript
easyui datagrid 大数据加载效率慢,优化解决方法(推荐)
2016/11/09 Javascript
JavaScript门面模式详解
2017/10/19 Javascript
详解封装基础的angular4的request请求方法
2018/06/05 Javascript
在Webpack中用url-loader处理图片和字体的问题
2020/04/28 Javascript
nuxt.js服务端渲染中axios和proxy代理的配置操作
2020/11/06 Javascript
[46:09]2014 DOTA2华西杯精英邀请赛 5 25 LGD VS VG第三场
2014/05/26 DOTA
在Python的Bottle框架中使用微信API的示例
2015/04/23 Python
Python使用metaclass实现Singleton模式的方法
2015/05/05 Python
django 发送手机验证码的示例代码
2018/04/25 Python
pandas 对series和dataframe进行排序的实例
2018/06/09 Python
Django中celery执行任务结果的保存方法
2019/07/12 Python
python实现倒计时小工具
2019/07/29 Python
Python读取分割压缩TXT文本文件实例
2020/02/14 Python
python对execl 处理操作代码
2020/06/22 Python
使用python实现学生信息管理系统
2021/02/25 Python
MADE荷兰:提供原创设计师家具
2018/04/03 全球购物
广州地球村科技数据库题目
2016/04/25 面试题
.NET面试问题集
2015/12/08 面试题
公司财务总监岗位职责
2013/12/14 职场文书
建筑经济管理专业求职信分享
2014/01/06 职场文书
优秀大学生的自我评价
2014/01/16 职场文书
毕业实习单位意见
2015/06/04 职场文书
远程教育集中轮训基层干部培训班学习心得体会
2016/01/09 职场文书
如何优化vue打包文件过大
2022/04/13 Vue.js