作为普通的web开发,通常都会涉及到post/get方式来请求server,接下来我们要用Node.js来实现一个上传图片并浏览的功能,所以要先解决post数据的处理问题。
在html页面中,创建一个form标签,action为/upload(或其他你喜欢的名称),method设为post,如下:
<form action="/upload" method="post"><textarea name="text" rows="20" cols="50"></textarea><inputtype="submit" value="上传" /></form>
那代码该怎么改呢?除了会在html中写一个简单的post form,还需要知道在Node.js中如何处理request请求,因为post数据就是存在于request中。其中,request对象提供的addListener有关于非阻塞请求(以后慢慢介绍)的处理方式。
“这里采用非阻塞方式处理是明智的,因为POST请求一般都比较“重” —— 用户可能会输入大量的内容。用阻塞的方式处理大数据量的请求必然会导致用户操作的阻塞。
为了使整个过程非阻塞,Node.js会将POST数据拆分成很多小的数据块,然后通过触发特定的事件,将这些小数据块传递给回调函数。这里的特定的事件有
data
事件(表示新的小数据块到达了)以及
end
事件(表示所有的数据都已经接收完毕)。”
addListener = function(type, listener),其中type为data和end的时候都会回调function listerer。这样的话,我们就要把对request的事件监听,放到server模块中,当接收完所有数据,触发end事件,让其回调函数调用route模块进行处理即可。
先修改Server.js文件,增加对request的事件监听:
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请求的数据编码。 request.setEncoding("utf8"); request.addListener("data",function(data){ postData += data; console.log("Received POST data :")+data ; }); request.addListener("end",function(){ route(handle,pathname,response,postData); }) } http.createServer(onRequest).listen(8888); console.log("Server has started"); } exports.start = start;
在requestHandlers.js文件中完善start()函数,当请求/start时,页面要渲染出一个简单的submit页面。
var querystring = require("querystring") ; function start(response,postData){ 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" />'+ '</form>'+ '</body>'+ '</html>'; response.writeHead(200,{"Content-Type":"text/html"}); response.write(body) ; response.end(); return ("Request handler 'start' was called."); } function upload(response, postData){ response.writeHead(200,{"Content-Type":"text/plain"}); //这里会把post的数据,写到html页面上。 response.write("Upload the postData: "+ querystring.parse(postData).text); response.end(); return ("Request handler 'upload' was called."); } exports.start = start; exports.upload = upload;
还有,根据上面两处代码的修改,不要忘记 给route模块的route方法增加postData参数。对于404(statusCode)的处理,IE下会默认显示自己的404页面,chrome浏览器,会显示write上去的数据。
启动WebStorm,可以通过断点方式,看一下这个简单的post处理流程。结果如下截图:
很容易想到,如果我们把textarea换做一个类upload标签(formidable),就可以完成图片上传的功能.这部分功能,接下来会做一种实现。