轻松创建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中转换URL字符串与查询字符串详解
Nov 26 NodeJs
NodeJS学习笔记之Connect中间件模块(二)
Jan 27 NodeJs
nodejs中实现阻塞实例
Mar 24 NodeJs
NodeJS与HTML5相结合实现拖拽多个文件上传到服务器的实现方法
Jul 26 NodeJs
NodeJS使用formidable实现文件上传
Oct 27 NodeJs
用nodejs搭建websocket服务器
Jan 23 NodeJs
Windows下使用Nodejs运行js的方法
Sep 02 NodeJs
nodejs acl的用户权限管理详解
Mar 14 NodeJs
NodeJs搭建本地服务器之使用手机访问的实例讲解
May 12 NodeJs
基于Nodejs的Tcp封包和解包的理解
Sep 19 NodeJs
详解NodeJS Https HSM双向认证实现
Mar 12 NodeJs
nodejs利用readline提示输入内容实例代码
Jul 15 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
第4章 数据处理-php正则表达式-郑阿奇(续)
2011/07/04 PHP
php生成静态文件的多种方法分享
2012/07/17 PHP
codeigniter教程之多文件上传使用示例
2014/02/11 PHP
php获取excel文件数据
2017/04/21 PHP
js中cookie的使用详细分析
2008/05/28 Javascript
jQuery之浮动窗口实现代码(两种方法)
2010/09/08 Javascript
jquery图片不完全按比例自动缩小的简单代码
2013/07/29 Javascript
js与jQuery 获取父窗、子窗的iframe
2013/12/20 Javascript
js自动生成的元素与页面原有元素发生堆叠的解决方法
2014/09/04 Javascript
对JavaScript客户端应用编程的一些建议
2015/06/24 Javascript
分享12个实用的jQuery代码片段
2016/03/09 Javascript
深入浅出讲解ES6的解构
2016/08/03 Javascript
jQuery中get方法用法分析
2016/12/07 Javascript
Javascript Function.prototype.bind详细分析
2016/12/29 Javascript
jQuery EasyUI开发技巧总结
2017/09/26 jQuery
VS Code转换大小写、修改选中文字或代码颜色的方法
2017/12/15 Javascript
element 结合vue 在表单验证时有值却提示错误的解决办法
2018/01/22 Javascript
angular4强制刷新视图的方法
2018/10/09 Javascript
解决vue elementUI 使用el-select 时 change事件的触发问题
2020/11/17 Vue.js
Python中的super用法详解
2015/05/28 Python
Python2.x版本中基本的中文编码问题解决
2015/10/12 Python
Windows安装Python、pip、easy_install的方法
2017/03/05 Python
Python读取sqlite数据库文件的方法分析
2017/08/07 Python
django之session与分页(实例讲解)
2017/11/13 Python
Python异常对代码运行性能的影响实例解析
2018/02/08 Python
在PyCharm中批量查找及替换的方法
2019/01/20 Python
对Python Class之间函数的调用关系详解
2019/01/23 Python
python实现计算器功能
2019/10/31 Python
Pytorch实现WGAN用于动漫头像生成
2021/03/04 Python
HTML5+CSS3 诱人的实例:3D立方体旋转动画实例
2016/12/30 HTML / CSS
德国的各种媒体在线商店:Thalia.de(书籍、电子书、玩具等)
2020/10/08 全球购物
2014年工程部工作总结
2014/11/25 职场文书
详解PHP用mb_string处理windows中文字符
2021/05/26 PHP
mysql获取指定时间段中所有日期或月份的语句(不设存储过程,不加表)
2021/06/18 MySQL
草系十大最强宝可梦,纸片人上榜,榜首大家最熟悉
2022/03/18 日漫
baselines示例程序train_cartpole.py的ImportError
2022/05/20 Python