轻松创建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实现Websocket的数据接收与发送
Nov 19 NodeJs
nodejs加密Crypto的实例代码
Jul 07 NodeJs
详解Nodejs基于mongoose模块的增删改查的操作
Dec 21 NodeJs
nodejs中art-template模板语法的引入及冲突解决方案
Nov 07 NodeJs
nodejs 最新版安装npm 的使用详解
Jan 18 NodeJs
nodejs+express搭建多人聊天室步骤
Feb 12 NodeJs
nodejs+mongodb aggregate级联查询操作示例
Mar 17 NodeJs
Nodejs 发布自己的npm包并制作成命令行工具的实例讲解
May 15 NodeJs
详解从NodeJS搭建中间层再谈前后端分离
Nov 13 NodeJs
详解NodeJS Https HSM双向认证实现
Mar 12 NodeJs
详解nodejs http请求相关总结
Mar 31 NodeJs
typescript nodejs 依赖注入实现方法代码详解
Jul 21 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
Mysql的常用命令
2006/10/09 PHP
php SQL防注入代码集合
2008/04/25 PHP
php打造属于自己的MVC框架
2012/03/07 PHP
js为空或不是对象问题的快速解决方法
2013/12/11 Javascript
node.js中的buffer.toJSON方法使用说明
2014/12/14 Javascript
jQuery中Form相关知识汇总
2015/01/06 Javascript
JavaScript中的条件判断语句使用详解
2015/06/03 Javascript
图解Sublime Text3使用技巧
2015/12/21 Javascript
浅谈JavaScript的计时器对象
2016/12/26 Javascript
详解Vue CLI3配置之filenameHashing使用和源码设计使用和源码设计
2018/08/31 Javascript
跨域解决之JSONP和CORS的详细介绍
2018/11/21 Javascript
详解用vue2.x版本+adminLTE开源框架搭建后台应用模版
2019/03/15 Javascript
JavaScript一元正号运算符示例代码
2019/06/30 Javascript
taro 实现购物车逻辑的实例代码
2020/06/05 Javascript
Vue中 axios delete请求参数操作
2020/08/25 Javascript
vue使用video插件vue-video-player的示例
2020/10/03 Javascript
[51:17]完美世界DOTA2联赛循环赛Inki vs DeMonsTer 第二场 10月30日
2020/10/31 DOTA
对Python新手编程过程中如何规避一些常见问题的建议
2015/04/01 Python
Python编程中字符串和列表的基本知识讲解
2015/10/14 Python
Django 解决上传文件时,request.FILES为空的问题
2020/05/20 Python
django Model层常用验证器及自定义验证器详解
2020/07/15 Python
利用django创建一个简易的博客网站的示例
2020/09/29 Python
Python Serial串口基本操作(收发数据)
2020/11/06 Python
HTML5注册页面示例代码
2014/03/27 HTML / CSS
HTML5 Canvas基本线条绘制的实例教程
2016/03/17 HTML / CSS
canvas像素点操作之视频绿幕抠图
2018/09/11 HTML / CSS
德国奢侈品网上商城:Mytheresa
2016/08/24 全球购物
英国HYPE双肩包官网:英国本土时尚潮牌
2018/09/26 全球购物
定制别致的瑜伽垫:Sugarmat
2019/06/21 全球购物
一夜的工作教学反思
2014/02/08 职场文书
会计专业求职信范文
2014/03/16 职场文书
2014年基建工作总结
2014/12/12 职场文书
Python绘制地图神器folium的新人入门指南
2021/05/23 Python
浅谈Python数学建模之固定费用问题
2021/06/23 Python
Feign调用传输文件异常的解决
2021/06/24 Java/Android
浅谈Python中对象是如何被调用的
2022/04/06 Python