- 我們接著前面的文檔
- 目標(biāo):顯示一個(gè)文本區(qū)(textarea)輸入內(nèi)容,然后通過(guò)POST請(qǐng)求提交給服務(wù)器创葡,服務(wù)器收到請(qǐng)求,公國(guó)程序?qū)⑤斎氲膬?nèi)容展示到瀏覽器中
這里我們新建一個(gè)post.html 用來(lái)存放靜態(tài)頁(yè)绢慢,然后通過(guò)引用fs模塊將其讀取導(dǎo)入
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>post提交數(shù)據(jù)</title>
</head>
<body>
<form action="/upload" method="post">
<textarea name="text" id="" cols="30" rows="20"></textarea>
<input type="submit" value="上傳">
</form>
</body>
</html>
以及新建一個(gè)postHandlers.js用來(lái)處理請(qǐng)求
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;
為了使整個(gè)過(guò)程非阻塞灿渴,node會(huì)將post數(shù)據(jù)拆分成很多小的數(shù)據(jù)塊,然后通過(guò)觸發(fā)特定的時(shí)間,講這些小數(shù)據(jù)塊傳遞給回調(diào)函數(shù)骚露。特定事件指data事件和end事件。我們?cè)趓equest對(duì)象上注冊(cè)監(jiān)聽(tīng)器來(lái)實(shí)現(xiàn)荸百。request每次接到http請(qǐng)求的時(shí)候,都會(huì)把該對(duì)象傳遞給onRequest回調(diào)函數(shù)够话。
獲取所有來(lái)自請(qǐng)求的數(shù)據(jù),然后將這些數(shù)據(jù)給應(yīng)用層處理女嘲,應(yīng)該是http服務(wù)區(qū)要做的是,建議直接在服務(wù)器中處理post數(shù)據(jù)欣尼,然后將最終的數(shù)據(jù)傳遞給請(qǐng)求路由和請(qǐng)求處理器
將data 和 end 事件的回調(diào)函數(shù)直接放在服務(wù)器中,在data時(shí)間回調(diào)中手機(jī)所有的post數(shù)據(jù)愕鼓,當(dāng)接收到所有數(shù)據(jù)觸發(fā)end事件后钙态,其回調(diào)函數(shù)調(diào)用請(qǐng)求路由菇晃,并將數(shù)據(jù)傳遞給他,然后磺送,請(qǐng)求路由再講改數(shù)據(jù)傳遞給請(qǐng)求處理程序驻子。
修改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;
上述代碼做了三件事:首先估灿,設(shè)置了接受數(shù)據(jù)的編碼格式為UTF-8,然后注冊(cè)了data事件的監(jiān)聽(tīng)器馅袁,用于收集每次接收到的新數(shù)據(jù)塊,并將其賦值給postData變量汗销,最后,我們將請(qǐng)求路由的調(diào)用一到end事件處理程序中大溜,確保他只會(huì)當(dāng)所有數(shù)據(jù)接收完畢后才觸發(fā),并只觸發(fā)一次钦奋。同事還把post數(shù)據(jù)傳遞給請(qǐng)求路由座云,因?yàn)檫@些程序,請(qǐng)求處理程序會(huì)用到
想要在/upload頁(yè)面展示用戶輸入的內(nèi)容朦拖,需要將postData傳遞給請(qǐng)求處理程序,修改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;
在瀏覽器訪問(wèn)localhost/start 然后在文本框輸入內(nèi)容璧帝,提交后就會(huì)跳轉(zhuǎn)到/upload并顯示輸入的內(nèi)容了。