Node之HTTP服務器創建服務器和獲取客戶端請求數據

創建HTTP服務器

在Node.js中,可以很方便地創建一個HTTP服務器,只需調用http模塊中的create Server方法即可

var server=http.createServer([requestListener])

在createServer方法中,可以使用一個可選參數,參數值爲一個回調函數,用於指定當接收到客戶端請求時所需執行的處理,該回調函數的指定方法如下所示。

function (request,response) {
//回調函數代碼略
}

  • request:代表一個客戶端請求
  • response:代表一個服務器端響應對象

createServer方法返回被創建的服務器對象,如果不在createServer方法中使用參數,也可以通過監聽該方法創建的服務器對象的request事件(當接收到客戶端請求時觸發),並且指定該事件觸發時調用的回調函數的方法來指定當接收到客戶端請求時所需執行的處理,代碼如下所示(代碼中的server代表一個HTTP服務器)。

server.on('request',function(request,response){
    //回調函數代碼略
});

在創建了HTTP服務器後,需要指定該服務器所要監聽的地址(可以爲一個IP地址,也可以爲一個主機名)及端口,這時,可以使用該HTTP服務器的listen方法

server.listen(port,[host],[backlog],[callback])
  • port:端口號
  • host:主機
  • backlog:最大連接數
  • callback:回調

也可使用listening事件實現

server.on('listening',function(){
    //回調函數代碼略
});

創建一個服務器完整示例:

var http = require('http');
var server=http.createServer(function (req, res) {
    //暫不指定接收到客戶端請求時的處理
}).listen(1337, "127.0.0.1",function(){
    console.log('服務器端開始監聽。');
});

close()關閉服務器

server.close();

可以監聽服務器被關閉以後

server.on('close',function(){
    //回調函數代碼略
});

監聽服務器錯誤信息

server.on('error', function (e) {
    if (e.code == 'EADDRINUSE') {//當地址及端口被佔用時錯誤代碼爲'EADDRINUSE'
        //可以在此處指定當地址及端口被佔用時所需執行的處理
    }
});

長鏈接

在默認情況下,客戶端和服務器端每進行一次HTTP操作,都將建立一次連接,客戶端與服務器端之間的交互通信完成後該連接就中斷。在HTTP1.1中,添加了長連接支持。如果客戶端發出的請求頭信息或者服務器端發出的響應頭信息中加入了“Connection:keep-alive”信息,則HTTP連接將繼續保持,客戶端可以繼續通過相同的連接向服務器端發出請求。

在Node.js中,當客戶端與服務器端建立連接時,觸發HTTP服務器對象的connection事件,可以監聽該事件並在該事件觸發時調用的回調函數中指定當連接建立時所需要執行的處理

server.on('connection',function(socket){
    //回調函數代碼略
});

在該回調函數中可以使用一個參數,參數值爲服務器端用於監聽客戶端請求的socket端口對象。

設置服務器的超時時間

可以使用HTTP服務器的setTimeout方法來設置服務器的超時時間。當該超時時間超過之後,客戶端不可繼續利用本次與HTTP服務器建立的連接,下次向該HTTP服務器發出請求時必須重新建立連接。

server.setTimeout(msecs, callback)
  • mecs:參數值爲一個整數,用於設置服務器的超時時間,單位爲毫秒,可以通過將該參數值設置爲0的方法取消服務器的超時處理。
  • callback:用於設置當服務器超時時調用的回調函數,在該回調函數中可以使用一個參數,參數值爲服務器端用於監聽客戶端請求的socket對象。
server.on('timeout',function(socket){
    //回調函數代碼略
});

獲取客戶端請求信息

HTTP服務器接收到客戶端請求時調用的回調函數中的第一個參數值爲一個http.IncomingMessage對象,該對象用於讀取客戶端請求流中的數據,因此,當從客戶端請求流中讀取到新的數據時觸發data事件,當讀取完客戶端請求流中的數據時觸發end事件。當該對象被用於讀取客戶端請求流中的數據時,該對象擁有如下所示的一些屬性。

  • method:該屬性值爲一個字符串,字符串值爲客戶端向服務器端發送請求時使用的方法,例如“GET”、“POST”、“PUT”或“DELETE”。
  • url:該屬性值爲客戶端發送請求時使用的URL參數字符串,例如“/”、“/user/1”、“/post/new/?param=value”。該屬性爲一個非常重要的屬性,通常用來判斷客戶端請求的頁面及需要執行的處理。
  • headers:該屬性值爲客戶端發送的請求頭對象,其中存放了客戶端發送的所有請求頭信息,包括各種cookie信息以及瀏覽器的各種信息。
  • httpVersion:該屬性值爲一個字符串,字符串值爲客戶端發送的HTTP版本,可能的值爲“1.1”或“1.0”。
  • trailers:該屬性值爲客戶端發送的trailer對象。該對象中存放了客戶端附加的一些HTTP頭信息,該對象被包含在客戶端發送的請求數據之後,因此只有當http.IncomingMessage對象的end事件觸發之後才能讀取到trailer對象中的信息。
  • socket:該屬性值爲服務器端用於監聽客戶端請求的socket對象。

獲取請求數據

var http = require('http');
var fs = require('fs');
var server=http.createServer(function (req, res) {
    if(req.url!=="/favicon.ico"){
        req.on('data',function(data){
        console.log('服務器端接收到數據:'+decodeURIComponent(data));
        });
        req.on('end',function(){
        console.log('客戶端請求數據已全部接收完畢。');
        });
    }
    res.end();
}).listen(1337, "127.0.0.1");

轉換URL字符串與查詢字符串

在Node.js中,提供了一個url模塊與一個QueryString模塊,分別用來轉換完整URL字符串與URL中的查詢字符串。

在一個完整的URL字符串中,從“?”字符之後(不包括“?”字符)到“#”字符之前(如果存在“#”字符)或者到該URL字符串結束(如果不存在“#”字符)的這一部分稱爲查詢字符串,例如在“http://google.com/user.php?userName=Lulingniu&age=40&sex=male#hash”這個URL字符串中,“userName=Lulingniu&age=40&sex=male”這個部分稱爲一個查詢字符串。

Query String模塊中的parse方法

可以使用Query String模塊中的parse方法將該字符串轉換爲一個對象

querystring.parse(str,[sep],[eq],[options])
  • str:用於指定被轉換的查詢字符串;
  • sep:用於指定該查詢字符串中的分割字符,默認參數值爲“&”
  • eq:用於指定該查詢字符串中的分配字符,默認參數值爲“=”
  • options:options參數值爲一個對象,可以在該對象中使用一個整數值類型的maxKeys屬性來指定轉換後的對象中的屬性個數,如果將maxKeys屬性值設定爲0,其效果等於不使用maxKeys屬性值。

Query String模塊中的stringify方法

可以使用Query String模塊中的stringify方法將對象轉換爲一個查詢字符串

querystring.stringify(obj,[sep],[eq])
  • obj:用於指定被轉換的對象;
  • sep:用於指定查詢字符串中所使用的分割字符,默認參數值爲“&”;
  • eq:用於指定查詢字符串中使用的分配字符,默認參數值爲“=”。

url.parse()

在url模塊中,可以使用parse方法將URL字符串轉換爲一個對象,根據URL字符串中的不同內容,該對象中可能具有的屬性及其含義如下所示。

  • href:被轉換的原URL字符串。
  • protocol:客戶端發出請求時使用的協議。
  • slashes:在協議與路徑中間是否使用“//”分隔符。
  • host:URL字符串中的完整地址及端口號,該地址可能爲一個IP地址,也可能爲一個主機名。
  • auth:URL字符串中的認證信息部分。
  • hostname:URL字符串中的完整地址,該地址可能爲一個IP地址,也可能爲一個主機名。
  • port:URL字符串中的端口號。
  • pathname:URL字符串中的路徑,不包含查詢字符串。
  • search:URL字符串中的查詢字符串,包含起始字符“?”。
  • path:URL字符串中的路徑,包含查詢字符串。
  • query:URL字符串中的查詢字符串,不包含起始字符“?”,或根據該查詢字符串而轉換的對象(根據parse方法所用參數而決定query屬性值)。
  • hash:URL字符串中的散列字符串,包含起始字符“#”。
url.parse(urlStr,[parseQueryString])
  • urlStr:用於指定需要轉換的URL字符串;
  • parseQueryString:爲一個布爾類型的參數,當參數值爲true時,內部使用Query String模塊將查詢字符串轉換爲一個對象,參數值爲false時不執行該轉換操作,默認參數值爲false。

url.format()

可以使用url模塊中的format方法將URL字符串經過轉換後的對象還原爲一個URL字符串。

url.format(urlObj)

url.resolve()

可以使用resolve方法將兩個方法結合成爲一個路徑

url.resolve(from,to
  • from:起點路徑字符串
  • to:參考路徑字符串

在resolve方法中,使用兩個字符串類型的參數,其中第一個參數爲起點路徑字符串,第二個參數爲參考路徑字符串。這兩個路徑既可爲相對路徑,也可爲絕對路徑。該方法返回轉換後的路徑。

在結合路徑時,以第一參數值爲起點路徑,執行如下所示的轉換規則。

  • 如果起點路徑爲網絡路徑,參考路徑爲非網絡路徑的絕對路徑,則返回路徑爲網絡根目錄+參考路徑。
  • 在其他情況下,如果參考路徑爲絕對路徑,則返回路徑爲該參考路徑。
  • 如果起點路徑爲一個不以“/”字符結尾的根目錄且參考路徑爲相對路徑,則返回路徑爲:起點路徑+“/”+參考路徑中去除開頭的“./”字符或“…/”字符(如果存在的話)後的文字。如果起點路徑爲一個以“/”字符結尾的根目錄且參考路徑爲相對路徑,則返回起點路徑+參考路徑中去除開頭的“./”字符或“…/”字符(如果存在的話)後的文字。
  • 如果起點路徑爲一個不以“/”字符結尾的子目錄且參考路徑爲相對路徑,同時開頭字符不爲“./”或“…/”,則返回路徑爲:起點路徑的上層目錄+“/”+參考路徑。如果起點路徑爲一個以“/”字符結尾的子目錄且參考路徑爲相對路徑,同時開頭字符不爲“./”或“…/”,則返回路徑爲:起點路徑的上層目錄+“/”+參考路徑。
  • 如果起點路徑爲一個不以“/”字符結尾的子目錄且參考路徑爲相對路徑,同時開頭字符爲“./”,則返回路徑爲:起點路徑的上層目錄+“/”+參考路徑中去除開頭的“./”字符後的文字。如果起點路徑爲一個以“/”字符結尾的子目錄且參考路徑爲相對路徑,同時開頭字符爲“./”,則返回起點路徑+參考路徑中去除開頭的“./”字符後的文字。
  • 如果起點路徑爲一個不以“/”字符結尾的子目錄且參考路徑爲相對路徑,同時開頭字符爲“…/”,則返回路徑爲:起點路徑的上層目錄的上層目錄+“/”+參考路徑中去除開頭的“…/”字符後的文字。如果起點路徑爲一個以“/”字符結尾的子目錄且參考路徑爲相對路徑,同時開頭字符爲“…/”,則返
    回起點路徑的上層目錄+參考路徑中去除開頭的“…/”字符後的文字。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章