- 我们接着前面的文档
- 目标:显示一个文本区(textarea)输入内容,然后通过POST请求提交给服务器,服务器收到请求,公国程序将输入的内容展示到浏览器中
这里我们新建一个post.html 用来存放静态页,然后通过引用fs模块将其读取导入
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>post提交数据</title>
</head>
<body>
<form action="/upload" method="post">
<textarea name="text" id="" cols="30" rows="20"></textarea>
<input type="submit" value="上传">
</form>
</body>
</html>
以及新建一个postHandlers.js用来处理请求
var fs = require('fs');
var querystring = require('querystring');
function start(response,postData) {
console.log('do post start');
var body = fs.readFileSync('./post.html');
response.writeHead(200,{"Content-Type":"text/html;charset:utf-8"});
response.write(body);
response.end();
}
function upload(response,postData) {
console.log('do upload');
response.writeHead(200,{"Content-Type":"text/plain"});
response.write("you've sent:"+querystring.parse(postData).texts);
response.end();
}
exports.start = start;
exports.upload = upload;
为了使整个过程非阻塞,node会将post数据拆分成很多小的数据块,然后通过触发特定的时间,讲这些小数据块传递给回调函数。特定事件指data事件和end事件。我们在request对象上注册监听器来实现。request每次接到http请求的时候,都会把该对象传递给onRequest回调函数。
获取所有来自请求的数据,然后将这些数据给应用层处理,应该是http服务区要做的是,建议直接在服务器中处理post数据,然后将最终的数据传递给请求路由和请求处理器
将data 和 end 事件的回调函数直接放在服务器中,在data时间回调中手机所有的post数据,当接收到所有数据触发end事件后,其回调函数调用请求路由,并将数据传递给他,然后,请求路由再讲改数据传递给请求处理程序。
修改server.js
var http = require('http');
var url =require('url');
function start(route,handle) {
function onRequest(request,response) {
var pathname = url.parse(request.url).pathname;
if (pathname === '/favicon.ico') {
}else{
var postData="";
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(80);
console.log('server running at 80');
}
exports.start = start;
上述代码做了三件事:首先,设置了接受数据的编码格式为UTF-8,然后注册了data事件的监听器,用于收集每次接收到的新数据块,并将其赋值给postData变量,最后,我们将请求路由的调用一到end事件处理程序中,确保他只会当所有数据接收完毕后才触发,并只触发一次。同事还把post数据传递给请求路由,因为这些程序,请求处理程序会用到
想要在/upload页面展示用户输入的内容,需要将postData传递给请求处理程序,修改router.js
function route(handle,pathname,response,postData) {
if (typeof handle[pathname] ==='function') {
return handle[pathname](response,postData);
}else{
console.log('no request'+pathname);
response.writeHead(404,{"Content-Type":"text/plain"});
response.write('404 NOT FOUND');
response.end();
}
}
exports.route = route;
在浏览器访问localhost/start 然后在文本框输入内容,提交后就会跳转到/upload并显示输入的内容了。