轻松创建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的模块写法入门(实例代码)
Mar 07 NodeJs
使用upstart把nodejs应用封装为系统服务实例
Jun 01 NodeJs
使用forever管理nodejs应用教程
Jun 03 NodeJs
Nodejs实战心得之eventproxy模块控制并发
Oct 27 NodeJs
nodejs根据ip数组在百度地图中进行定位
Mar 06 NodeJs
NodeJS测试框架mocha入门教程
Mar 28 NodeJs
用Nodejs搭建服务器访问html、css、JS等静态资源文件
Apr 28 NodeJs
nodejs创建简易web服务器与文件读写的实例
Sep 07 NodeJs
Nodejs中crypto模块的安全知识讲解
Jan 03 NodeJs
nodejs简单实现TCP服务器端和客户端的聊天功能示例
Jan 04 NodeJs
nodejs express配置自签名https服务器的方法
May 22 NodeJs
nodejs 使用nodejs-websocket模块实现点对点实时通讯
Nov 28 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中使用Oracle数据库(4)
2006/10/09 PHP
使用 php4 加速 web 传输
2006/10/09 PHP
php 字符串函数收集
2010/03/29 PHP
php获取网页标题和内容函数(不包含html标签)
2014/02/03 PHP
ucenter中词语过滤原理分析
2016/07/13 PHP
PHP异常处理定义与使用方法分析
2017/07/25 PHP
多广告投放代码 推荐
2006/11/13 Javascript
Script的加载方法小结
2011/01/12 Javascript
关于jquery中全局函数each使用介绍
2013/12/10 Javascript
jquery文档操作wrap()方法实例简述
2015/01/10 Javascript
AngularJs中Bootstrap3 datetimepicker使用实例
2016/12/13 Javascript
angularjs $http实现form表单提交示例
2017/06/09 Javascript
React Native 集成jpush-react-native的示例代码
2017/08/16 Javascript
浅谈express 中间件机制及实现原理
2017/08/31 Javascript
AngularJS实现图片上传和预览功能的方法分析
2017/11/08 Javascript
swiper实现异形轮播效果
2019/11/28 Javascript
如何基于JavaScript判断图片是否加载完成
2019/12/28 Javascript
VUE+elementui组件在table-cell单元格中绘制微型echarts图
2020/04/20 Javascript
从源码角度来回答keep-alive组件的缓存原理
2021/01/18 Javascript
Python和php通信乱码问题解决方法
2014/04/15 Python
web.py在模板中输出美元符号的方法
2014/08/26 Python
python实现的文件夹清理程序分享
2014/11/22 Python
基python实现多线程网页爬虫
2015/09/06 Python
Python for Informatics 第11章 正则表达式(一)
2016/04/21 Python
Python脚本实现Web漏洞扫描工具
2016/10/25 Python
Python实现的tcp端口检测操作示例
2018/07/24 Python
Pycharm 2020.1 版配置优化的详细教程
2020/08/07 Python
OpenCV利用python来实现图像的直方图均衡化
2020/10/21 Python
加拿大品牌鞋包连锁店:Little Burgundy
2021/02/28 全球购物
小学生2014国庆节演讲稿:祖国在我心中
2014/09/21 职场文书
机电专业毕业生自我鉴定2014
2014/10/04 职场文书
党的群众路线教育实践活动对照检查剖析材料
2014/10/09 职场文书
看雷锋电影观后感
2015/06/10 职场文书
消防安全主题班会
2015/08/12 职场文书
日本十大血腥动漫,那些被禁播的动漫盘点
2022/03/21 日漫
Nginx配置根据url参数重定向
2022/04/11 Servers