概念:Node.js提供了http模組。其中封裝了一個高效的HTTP伺服器和一個簡單的HTTP用戶端。
http.server是一個基於事件的HTTP伺服器。內部用C++實現。介面由JavaScript封裝。
http.request則是一個HTTP用戶端工具。使用者向伺服器發送請求。
一、HTTP伺服器
http.Server實現的,它提供了一套封裝層級很低的API,僅僅是流量控制和簡單的解析,所有的高層功能都需要通過它的介面
前面講解的app.js案例
程式碼分析:
http.createServer建立了一個http.Server的執行個體,將一個函數作為HTTP請求處理函數。這個函數接受兩個參數,請求對象req和響應對象的res。
res顯式寫入了響應代碼200(表示請求成功),指定回應標頭,寫入響應體。調用end結束並發送。該執行個體調用listen函數,啟動伺服器並監聽3000連接埠。
1.http.Server的事件
http.Server是一個基於事件的HTTP伺服器,所有請求都被封裝到獨立的事件,開發人員只要對它的事件編寫相應的函數即可實現HTTP伺服器的所有功能,
它繼承與EventEmitter,提供了以下事件:
request:當用戶端請求到來時,該事件被觸發,提供兩個參數req和res,分別是http.ServerRequest和http.ServerResponse的執行個體,表示請求和響應資訊。
connection:當TCP串連建立時,該事件被觸發,提供一個參數socket,為net.Socket的執行個體(底層協議對象)。
close:當伺服器關閉時,該事件被觸發。
除此之外還有checkContinue、upgrade、clientError事件。
最常用和關心的是:request事件,http提供了一個捷徑,http.createServer([requestListener])
顯式實現方法:
案例:server.js
var http = require('http');
var server = new http.Server();
server.on('request',function(req,res){
res.writeHead(200,{'Content-Type':'text/html'});
res.write('NODE.JS');
res.end('
hello,world
');
});
server.listen(3000);
2.http.ServerRequest請求的資訊
此對象是後端開發人員最關注的內容,它一般由http.Server的request對象發送,作為第一個參數傳遞,通常簡寫成request或req。
HTTP請求分為兩部分:要求標頭和請求體。,請求內容短的直接在要求標頭解析完成後立即讀取,而請求體可能相對較長,需要一定的時間傳輸,因此提供了3個事件用於控制請求體傳輸。
(1)data:當請求體資料到來時,該事件被觸發,該事件一共一個參數chunk,表示接受到的資料。
(2)end:當請求體資料轉送完成時,該事件被觸發,此後將不會再有資料到來。
(3)close:使用者當前請求結束時,該事件被觸發,不同於end,如果使用者強制終止了傳輸,也會觸發close
ServerReuqest的屬性
complete:用戶端請求是否已經發送完成
httpVersion HTTP協議版本,通常是1.0或1.1
method HTTP要求方法,如:GET,POST
url 原始的請求路徑,例如/pc/getUser或/user?name=marico
headers HTTP要求標頭
trailers HTTP請求尾(不常見)
connection 當前HTTP串連通訊端,為net.Socket的執行個體
socket connection屬性的別名
client client屬性的別名
3.擷取GET請求內容
由於GET請求直接被嵌入在路徑中,URL完整的請求路徑,包括了?後面的部分,因此你可以手動解析後面的內容作為GET的參數,Nodejs的url模組中的parse函數提供了這個功能
執行個體:get.js
var http=require('http');
var urls=require('url');
var util=require('util');
http.createServer(function(req,res){
res.writeHead(200,{'Content-Type':'text/plain'});
res.end(util.inspect(urls.parse(req.url,true)));
}).listen(3000);
4.擷取POST請求內容
POST請求的內容全部都在請求體中,http.ServerRequest並沒有一個屬性內容為請求體,原因是等待請求體傳輸可能是一件耗時的工作。譬如上傳檔案。
惡意的POST請求會大大消耗伺服器的資源。所以Nodejs是不會解析請求體,當你需要的時候,需要手動來做。
執行個體:post.js
var http=require('http');
var querystring=require('querystring');
var util=require('util');
http.createServer(function(req,res){
var post='';
//註冊data事件監聽函數,每當接受請求體的資料
req.on('data',function(chunk){
post+=chunk;
});
req.on('end',function(){
//解析成字串格式的post為真正的post請求格式
post=querystring.parse(post);
//向前端返回
res.end(util.inspect(post));
});
}).listen(3000);
5.http.ServerResponse返回給用戶端的資訊
決定了使用者最終能到的結果,它是由http.Server的reponse對象發送的,作為第二個參數傳遞。一般為response或res
主要的三個函數:
response.writeHead(statusCode,[headers]):向請求的用戶端發送回應標頭。
statusCode是HTTP的狀態代碼,如200為成功,404未找到等。
headers是一個類似關聯陣列的對象,表示回應標頭的每個屬性。
response.write(data,[encoding]) 向請求用戶端發送相應內容,data是buffer或字串,encoding為編碼
response.end([data],[encoding]) 結束響應,告知使用者所有發送已經完成,當所有要返回的內容發送完畢,該函數必須被調用一次,如果不調用,用戶端永遠處於等待狀態