Node中的http模塊詳解(服務端)

Node中的Http

Node中提供了http模塊,其中封裝了高效的http服務器和http客戶端 
http.server是一個基於事件的HTTP服務器,內部是由c++實現的,接口由JavaScript封裝 
http.request是一個HTTP客戶端工具。用戶向服務器發送數據。 
下面就來分別得介紹一下http的服務端和客戶端

一、HTTP服務器

http.Server實現的,它提供了一套封裝級別很低的API,僅僅是流控制和簡單的解析,所有的高層功能都需要通過它的接口。 
下面分別來講一個有關http服務器的幾個事件

1.http.server事件

http.server是一個基於事件的HTTP服務器,所有的請求都被封裝到獨立的事件當中,我們只需要對他的事件編寫相應的行數就可以實現HTTP服務器的所有功能,它繼承自EventEmitter,提供了以下的事件: 
1. request:當客戶端請求到來的時候,該事件被觸發,提供兩個參數requestresponse,分別是http.ServerRequesthttp.ServerResponse表示請求和響應的信息。 
2. connection:當TCP建立連接的時候,該事件被觸發,提供了一個參數socket,爲net.socket的實例(底層協議對象) 
3. close:當服務器關閉的時候會被觸發 
4. 除此之外還有checkContinue、upgrade、clientError等事件 
我們最常用的還是request事件,http也給這個事件提供了一個捷徑:http.createServer([requestListener]) 
下面我們來簡單的看一下兩個案例: 
第一個是使用request事件的:

const http = require('http');
const net  = require('net');
const util = require('util');
//隨便定義的一個函數,下面會用到
function  a(){
    console.log("dajiahao");
}
var server = new http.Server();
server.on('request',(req,res)=>{
    console.log(req.url);
    //設置應答頭信息
    res.writeHead(200,{'Content-Type':'text/html'});
    res.write('hello we are family<br>');
    res.end('server already end\n');
});
//顯示了三次這也證明了TCP的三次握手
server.on('connection',()=>{
    a();
});
server.on('close',()=>{
    console.log('server will close');
});
//關閉服務爲了觸發close事件
server.close();
server.listen(8080);

下面的案例使用http的給的捷徑http.createServer製作的代碼:

const http = require('http');
const net  = require('net');
const util = require('util');


http.createServer(function(req,res){
    res.writeHead(404,{'Content-Type':'text/plain'})
    res.write("we are is content");
    res.end("fdsa");

}).listen(3000);

2.http.ServerRequset請求信息

我們都知道HTTP請求分爲兩部分:請求頭請求體,如果請求的內容少的話就直接在請求頭協議完成之後立即讀取,請求體可能相對較長一點,需要一定的時間傳輸。因此提供了三個事件用於控制請求體傳輸
(1)data:當請求體數據到來時,該事件被觸發,該事件一共一個參數chunk,表示接受到的數據。 
(2)end:當請求體數據傳輸完成時,該事件被觸發,此後將不會再有數據到來。 
(3)close:用戶當前請求結束時,該事件被觸發,不同於end,如果用戶強制終止了傳輸,也會觸發close 
ServerRequest的屬性

名稱 含義
ccomplete 客戶端請求是否已經發送完成
httpVersion HTTP協議版本,通常是1.0或1.1
method HTTP請求方法,如:GET,POST
url 原始的請求路徑
headers HTTP請求頭
trailers HTTP請求尾(不常見)
connection 當前HTTP連接套接字,爲net.Socket的實例
socket connection屬性的別名
client client屬性的別名
http.createServer(function(req,res){
    console.log(req.httpVersion);
    //console.log(req.socket);
    console.log(req.headers);
    console.log(req.method);
    res.writeHead(404,{'Content-Type':'text/plain'})
    res.write("we are is content");
    res.end("fdsa");
}).listen(8080);

3.獲取GET請求內容

由於GET請求直接被嵌入在路徑中,URL完整的請求路徑,包括了?後面的部分,因此你可以手動解析後面的內容作爲GET的參數,Nodejs的url模塊中的parse函數提供了這個功能

const http = require('http');
const net  = require('net');
const url  = require('url');
const util = require('util');

http.createServer((req,res)=>{
    res.write(util.inspect(url.parse(req.url,true)));
    //利用url模塊去解析客戶端發送過來的URL
    res.end(util.inspect(url.parse(req.url,false)));
}).listen(8080);

4.獲得POST請求內容

POST請求的內容全部都在請求體中,http.ServerRequest並沒有一個屬性內容爲請求體,原因是等待請求體傳輸可能是一件耗時的工作。譬如上傳文件。惡意的POST請求會大大消耗服務器的資源。所以Nodejs是不會解析請求體,當你需要的時候,需要手動來做。 
簡單的看一下代碼:

const http = require('http');
const net  = require('net');
const url  = require('url');
const util = require('util');
//querystring用於處理URL中的查詢字符串
const querystring = require('querystring');

http.createServer((req,res)=>{
    var posr = '';
    req.on('data',(chunk)=>{
        post+=chunk;
    });
    res,on('end',()=>{
        //將字符串變爲json的格式
        post  =  querystring.parse(post);
        //向前端返回字符串
        res.end(util.inspect(post));
    });
})

5.http.ServerResponse返回客戶端信息

決定了用戶最終能到的結果,它是由http.Server的request事件發送的,作爲第二個參數傳遞。一般爲response或res 
主要的三個函數: 
response.writeHead(statusCode,[headers]):向請求的客戶端發送響應頭。 
statusCode是HTTP的狀態碼,如200爲成功,404未找到等。 
headers是一個類似關聯數組的對象,表示響應頭的每個屬性。 
response.write(data,[encoding]) 向請求客戶端發送相應內容,data是buffer或字符串,encoding爲編碼 
response.end([data],[encoding]) 結束響應,告知用戶所有發送已經完成,當所有要返回的內容發送完畢,該函數必須被調用一次,如果不調用,客戶端永遠處於等待狀態

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章