本课教你如何处理post请求
通过前面10节课的学习,你已经是新手中的专家了, 你会想到采用异步回调来实现非阻塞地处理post请求的数据。
这里采用非阻塞的处理方式是明智的,因为一般post请求都比较“重”, 用户可能会输入大量的内容。
为了使整个过程非阻塞,node.js 会将post数据拆分成很多小的数据块,然后通过触发特定的事件,将这些小数据块传递给回调函数。 这里的特定事件有data事件(表示新的小数据块到了) 还有 end事件(表示 所有的数据都已经接收完毕)
我们需要告诉node.js当这些事件触发的时候,回调哪些函数。
怎么告诉呢,通过在request对象上注册监听器(listener)来实现。 如下所示
通过前面10节课的学习,你已经是新手中的专家了, 你会想到采用异步回调来实现非阻塞地处理post请求的数据。
这里采用非阻塞的处理方式是明智的,因为一般post请求都比较“重”, 用户可能会输入大量的内容。
为了使整个过程非阻塞,node.js 会将post数据拆分成很多小的数据块,然后通过触发特定的事件,将这些小数据块传递给回调函数。 这里的特定事件有data事件(表示新的小数据块到了) 还有 end事件(表示 所有的数据都已经接收完毕)
我们需要告诉node.js当这些事件触发的时候,回调哪些函数。
怎么告诉呢,通过在request对象上注册监听器(listener)来实现。 如下所示
request.addListener("data", function(chunk){
//called when a new chunk of data was received
});
request.addlistener("end", function(){
// called when all chunks of data have been received
});
问题来了,写在哪里好呢?
request对象,是出现在server.js里的, 并且没有像response一样,继续向下传递。
那么,是应该直接写在server里呢,还是应该把request也向下传递,让下面的逻辑去处理呢?
在我看来, 获取所有来个请求的数据,然后再将数据给应用 层处理是http服务器应该要做的事情,所以应该把 data 和 end 事件回调放在服务器中。
马上来实现server.js吧:
request对象,是出现在server.js里的, 并且没有像response一样,继续向下传递。
那么,是应该直接写在server里呢,还是应该把request也向下传递,让下面的逻辑去处理呢?
在我看来, 获取所有来个请求的数据,然后再将数据给应用 层处理是http服务器应该要做的事情,所以应该把 data 和 end 事件回调放在服务器中。
马上来实现server.js吧:
function start(get, config){
var http = require("http");
var url = require("url");
var server = http.createServer(function(request, response){
var pathname = url.parse(request.url).pathname;
var postData = "";
request.setEncoding("utf8");
request.addListener("data", function(chunk){
//called when a new chunk of data was received
postData += chunk;
console.log("\r\n received new chunk:" + chunk);
});
request.addListener("end", function(){
// called when all chunks of data have been received
get(pathname, config, response, postData);
});
});
server.listen(8888);
}
exports.start = start;
新的代码做了三件事情
1. 添加了一个postData变量
2.设置了接收数据的编码格式为 utf-8
3.添加了data 和end函数, data中给postData增加数据块, end中,把全部的postData发给路由注入的路由模块函数 get去处理
下面接着 修改routes模块
1. 添加了一个postData变量
2.设置了接收数据的编码格式为 utf-8
3.添加了data 和end函数, data中给postData增加数据块, end中,把全部的postData发给路由注入的路由模块函数 get去处理
下面接着 修改routes模块
function get(pathname , config, response, postData){
console.log("routes to :"+pathname);
if (typeof(config[pathname]) === 'function') {
config[pathname](response, postData);
} else{
console.log("routes to empty path: " + pathname);
}
};
exports.get = get;
最后是 requestHandler模块, 记得我们的form.html里 action写的是 /upload 哟,所以也要添加一个相应的处理函数
var exec = require("child_process").exec;
var fs = require("fs");
function a(response, postData){
fs.readFile("./html/form.html", function(err, str){
if(err){
throw err;
}else{
response.writeHead(200,{"Content-Type":"text/html"});
response.write(str);
response.end();
}
});
}
function b(response, postData){
var content = "empty";
exec("find /",
{timeout:10000, maxBuffer:20000*1024},
function(error, stdout, stderr){
response.writeHead(200, {"Content-Type":"text/plain"});
response.write(stdout);
response.end();
});
}
function upload(response, postData){
response.writeHead(200, {"Content-Type":"text/plain"});
response.write("You have send data: "+postData);
response.end();
}
exports.a = a;
exports.b = b;
exports.upload = upload;
index.js里也要相应增加配置
config['/upload'] = requestHandler.upload;
重启服务 node index 访问 http://localhost:8888/a
看到表格后,随便写点内容abcd, 点submit 按钮, 在cli里,就能看到有如下信息
received new chunk:text=abcde
你还可以尝试下,输入巨量的内容,比如上万个字母,你会发现 data事件会触发多次。
好了,现在你已经学会如果接收post数据(在server.js中),并在请求处理程序中(在requestHandler.js中)处理该数据了。
最后,需要优化的是: 我们是把整个postData都传递给了路由(routes.js)和请求处理程序(requestHandler.js). 我们应该只把post数据中,我们感兴趣的一部分传递给它们两个, 在这里,我们感兴趣的只是 form.html中 name="text"的字段。
还记得 第五课 中介绍的querystring模块么, 我们用它来实现. 修改请求处理程序
看到表格后,随便写点内容abcd, 点submit 按钮, 在cli里,就能看到有如下信息
received new chunk:text=abcde
你还可以尝试下,输入巨量的内容,比如上万个字母,你会发现 data事件会触发多次。
好了,现在你已经学会如果接收post数据(在server.js中),并在请求处理程序中(在requestHandler.js中)处理该数据了。
最后,需要优化的是: 我们是把整个postData都传递给了路由(routes.js)和请求处理程序(requestHandler.js). 我们应该只把post数据中,我们感兴趣的一部分传递给它们两个, 在这里,我们感兴趣的只是 form.html中 name="text"的字段。
还记得 第五课 中介绍的querystring模块么, 我们用它来实现. 修改请求处理程序
var querystring = require("querystring");
function upload(response, postData){
response.writeHead(200, {"Content-Type":"text/plain"});
response.write("You have send data: "+querystring.parse(postData).text);
response.end();
}
好了, 重启 node index 访问 http://localhost:8888/a
在text 里随便 输入点内容 比如 bob ,点击 按钮,可以看到跳转到了 http://localhost:8888/upload
并且 页面显示 You have send data: bob
收工
在text 里随便 输入点内容 比如 bob ,点击 按钮,可以看到跳转到了 http://localhost:8888/upload
并且 页面显示 You have send data: bob
收工
lesson-11.zip |