創(chuàng)建HTTP服務(wù)器
在Node.js中芜赌,可以很方便地創(chuàng)建一個HTTP服務(wù)器冤寿,只需調(diào)用http模塊中的create Server方法即可
var server=http.createServer([requestListener])
在createServer方法中桥嗤,可以使用一個可選參數(shù),參數(shù)值為一個回調(diào)函數(shù)菇篡,用于指定當(dāng)接收到客戶端請求時所需執(zhí)行的處理,該回調(diào)函數(shù)的指定方法如下所示一喘。
function (request,response) {
//回調(diào)函數(shù)代碼略
}
- request:代表一個客戶端請求
- response:代表一個服務(wù)器端響應(yīng)對象
createServer方法返回被創(chuàng)建的服務(wù)器對象驱还,如果不在createServer方法中使用參數(shù)嗜暴,也可以通過監(jiān)聽該方法創(chuàng)建的服務(wù)器對象的request事件(當(dāng)接收到客戶端請求時觸發(fā)),并且指定該事件觸發(fā)時調(diào)用的回調(diào)函數(shù)的方法來指定當(dāng)接收到客戶端請求時所需執(zhí)行的處理议蟆,代碼如下所示(代碼中的server代表一個HTTP服務(wù)器)闷沥。
server.on('request',function(request,response){
//回調(diào)函數(shù)代碼略
});
在創(chuàng)建了HTTP服務(wù)器后,需要指定該服務(wù)器所要監(jiān)聽的地址(可以為一個IP地址咐容,也可以為一個主機(jī)名)及端口舆逃,這時,可以使用該HTTP服務(wù)器的listen方法
server.listen(port,[host],[backlog],[callback])
- port:端口號
- host:主機(jī)
- backlog:最大連接數(shù)
- callback:回調(diào)
也可使用listening事件實(shí)現(xiàn)
server.on('listening',function(){
//回調(diào)函數(shù)代碼略
});
創(chuàng)建一個服務(wù)器完整示例:
var http = require('http');
var server=http.createServer(function (req, res) {
//暫不指定接收到客戶端請求時的處理
}).listen(1337, "127.0.0.1",function(){
console.log('服務(wù)器端開始監(jiān)聽戳粒。');
});
close()關(guān)閉服務(wù)器
server.close();
可以監(jiān)聽服務(wù)器被關(guān)閉以后
server.on('close',function(){
//回調(diào)函數(shù)代碼略
});
監(jiān)聽服務(wù)器錯誤信息
server.on('error', function (e) {
if (e.code == 'EADDRINUSE') {//當(dāng)?shù)刂芳岸丝诒徽加脮r錯誤代碼為'EADDRINUSE'
//可以在此處指定當(dāng)?shù)刂芳岸丝诒徽加脮r所需執(zhí)行的處理
}
});
長鏈接
在默認(rèn)情況下路狮,客戶端和服務(wù)器端每進(jìn)行一次HTTP操作,都將建立一次連接蔚约,客戶端與服務(wù)器端之間的交互通信完成后該連接就中斷奄妨。在HTTP1.1中,添加了長連接支持苹祟。如果客戶端發(fā)出的請求頭信息或者服務(wù)器端發(fā)出的響應(yīng)頭信息中加入了“Connection:keep-alive”信息砸抛,則HTTP連接將繼續(xù)保持,客戶端可以繼續(xù)通過相同的連接向服務(wù)器端發(fā)出請求树枫。
在Node.js中直焙,當(dāng)客戶端與服務(wù)器端建立連接時,觸發(fā)HTTP服務(wù)器對象的connection事件团赏,可以監(jiān)聽該事件并在該事件觸發(fā)時調(diào)用的回調(diào)函數(shù)中指定當(dāng)連接建立時所需要執(zhí)行的處理
server.on('connection',function(socket){
//回調(diào)函數(shù)代碼略
});
在該回調(diào)函數(shù)中可以使用一個參數(shù)箕般,參數(shù)值為服務(wù)器端用于監(jiān)聽客戶端請求的socket端口對象。
設(shè)置服務(wù)器的超時時間
可以使用HTTP服務(wù)器的setTimeout方法來設(shè)置服務(wù)器的超時時間舔清。當(dāng)該超時時間超過之后丝里,客戶端不可繼續(xù)利用本次與HTTP服務(wù)器建立的連接,下次向該HTTP服務(wù)器發(fā)出請求時必須重新建立連接体谒。
server.setTimeout(msecs, callback)
- mecs:參數(shù)值為一個整數(shù)杯聚,用于設(shè)置服務(wù)器的超時時間,單位為毫秒抒痒,可以通過將該參數(shù)值設(shè)置為0的方法取消服務(wù)器的超時處理幌绍。
- callback:用于設(shè)置當(dāng)服務(wù)器超時時調(diào)用的回調(diào)函數(shù),在該回調(diào)函數(shù)中可以使用一個參數(shù)故响,參數(shù)值為服務(wù)器端用于監(jiān)聽客戶端請求的socket對象傀广。
server.on('timeout',function(socket){
//回調(diào)函數(shù)代碼略
});
獲取客戶端請求信息
HTTP服務(wù)器接收到客戶端請求時調(diào)用的回調(diào)函數(shù)中的第一個參數(shù)值為一個http.IncomingMessage對象,該對象用于讀取客戶端請求流中的數(shù)據(jù)彩届,因此伪冰,當(dāng)從客戶端請求流中讀取到新的數(shù)據(jù)時觸發(fā)data事件,當(dāng)讀取完客戶端請求流中的數(shù)據(jù)時觸發(fā)end事件樟蠕。當(dāng)該對象被用于讀取客戶端請求流中的數(shù)據(jù)時贮聂,該對象擁有如下所示的一些屬性靠柑。
- method:該屬性值為一個字符串,字符串值為客戶端向服務(wù)器端發(fā)送請求時使用的方法吓懈,例如“GET”歼冰、“POST”、“PUT”或“DELETE”耻警。
- url:該屬性值為客戶端發(fā)送請求時使用的URL參數(shù)字符串隔嫡,例如“/”、“/user/1”榕栏、“/post/new/?param=value”畔勤。該屬性為一個非常重要的屬性,通常用來判斷客戶端請求的頁面及需要執(zhí)行的處理扒磁。
- headers:該屬性值為客戶端發(fā)送的請求頭對象庆揪,其中存放了客戶端發(fā)送的所有請求頭信息,包括各種cookie信息以及瀏覽器的各種信息妨托。
- httpVersion:該屬性值為一個字符串缸榛,字符串值為客戶端發(fā)送的HTTP版本,可能的值為“1.1”或“1.0”兰伤。
- trailers:該屬性值為客戶端發(fā)送的trailer對象内颗。該對象中存放了客戶端附加的一些HTTP頭信息,該對象被包含在客戶端發(fā)送的請求數(shù)據(jù)之后敦腔,因此只有當(dāng)http.IncomingMessage對象的end事件觸發(fā)之后才能讀取到trailer對象中的信息均澳。
- socket:該屬性值為服務(wù)器端用于監(jiān)聽客戶端請求的socket對象。
獲取請求數(shù)據(jù)
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('服務(wù)器端接收到數(shù)據(jù):'+decodeURIComponent(data));
});
req.on('end',function(){
console.log('客戶端請求數(shù)據(jù)已全部接收完畢符衔。');
});
}
res.end();
}).listen(1337, "127.0.0.1");
轉(zhuǎn)換URL字符串與查詢字符串
在Node.js中找前,提供了一個url模塊與一個QueryString模塊,分別用來轉(zhuǎn)換完整URL字符串與URL中的查詢字符串判族。
在一個完整的URL字符串中躺盛,從“?”字符之后(不包括“?”字符)到“#”字符之前(如果存在“#”字符)或者到該URL字符串結(jié)束(如果不存在“#”字符)的這一部分稱為查詢字符串,例如在“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方法將該字符串轉(zhuǎn)換為一個對象
querystring.parse(str,[sep],[eq],[options])
- str:用于指定被轉(zhuǎn)換的查詢字符串;
- sep:用于指定該查詢字符串中的分割字符辩撑,默認(rèn)參數(shù)值為“&”
- eq:用于指定該查詢字符串中的分配字符界斜,默認(rèn)參數(shù)值為“=”
- options:options參數(shù)值為一個對象,可以在該對象中使用一個整數(shù)值類型的maxKeys屬性來指定轉(zhuǎn)換后的對象中的屬性個數(shù)合冀,如果將maxKeys屬性值設(shè)定為0锄蹂,其效果等于不使用maxKeys屬性值。
Query String模塊中的stringify方法
可以使用Query String模塊中的stringify方法將對象轉(zhuǎn)換為一個查詢字符串
querystring.stringify(obj,[sep],[eq])
- obj:用于指定被轉(zhuǎn)換的對象水慨;
- sep:用于指定查詢字符串中所使用的分割字符得糜,默認(rèn)參數(shù)值為“&”;
- eq:用于指定查詢字符串中使用的分配字符晰洒,默認(rèn)參數(shù)值為“=”朝抖。
url.parse()
在url模塊中,可以使用parse方法將URL字符串轉(zhuǎn)換為一個對象谍珊,根據(jù)URL字符串中的不同內(nèi)容治宣,該對象中可能具有的屬性及其含義如下所示。
- href:被轉(zhuǎn)換的原URL字符串砌滞。
- protocol:客戶端發(fā)出請求時使用的協(xié)議侮邀。
- slashes:在協(xié)議與路徑中間是否使用“//”分隔符。
- host:URL字符串中的完整地址及端口號贝润,該地址可能為一個IP地址绊茧,也可能為一個主機(jī)名。
- auth:URL字符串中的認(rèn)證信息部分打掘。
- hostname:URL字符串中的完整地址华畏,該地址可能為一個IP地址,也可能為一個主機(jī)名尊蚁。
- port:URL字符串中的端口號亡笑。
- pathname:URL字符串中的路徑,不包含查詢字符串横朋。
- search:URL字符串中的查詢字符串仑乌,包含起始字符“?”琴锭。
- path:URL字符串中的路徑晰甚,包含查詢字符串。
- query:URL字符串中的查詢字符串祠够,不包含起始字符“压汪?”,或根據(jù)該查詢字符串而轉(zhuǎn)換的對象(根據(jù)parse方法所用參數(shù)而決定query屬性值)古瓤。
- hash:URL字符串中的散列字符串止剖,包含起始字符“#”。
url.parse(urlStr,[parseQueryString])
- urlStr:用于指定需要轉(zhuǎn)換的URL字符串落君;
- parseQueryString:為一個布爾類型的參數(shù)穿香,當(dāng)參數(shù)值為true時,內(nèi)部使用Query String模塊將查詢字符串轉(zhuǎn)換為一個對象绎速,參數(shù)值為false時不執(zhí)行該轉(zhuǎn)換操作皮获,默認(rèn)參數(shù)值為false。
url.format()
可以使用url模塊中的format方法將URL字符串經(jīng)過轉(zhuǎn)換后的對象還原為一個URL字符串纹冤。
url.format(urlObj)
url.resolve()
可以使用resolve方法將兩個方法結(jié)合成為一個路徑
url.resolve(from,to
- from:起點(diǎn)路徑字符串
- to:參考路徑字符串
在resolve方法中洒宝,使用兩個字符串類型的參數(shù)购公,其中第一個參數(shù)為起點(diǎn)路徑字符串,第二個參數(shù)為參考路徑字符串雁歌。這兩個路徑既可為相對路徑宏浩,也可為絕對路徑。該方法返回轉(zhuǎn)換后的路徑靠瞎。
在結(jié)合路徑時比庄,以第一參數(shù)值為起點(diǎn)路徑,執(zhí)行如下所示的轉(zhuǎn)換規(guī)則乏盐。
- 如果起點(diǎn)路徑為網(wǎng)絡(luò)路徑佳窑,參考路徑為非網(wǎng)絡(luò)路徑的絕對路徑,則返回路徑為網(wǎng)絡(luò)根目錄+參考路徑父能。
- 在其他情況下神凑,如果參考路徑為絕對路徑,則返回路徑為該參考路徑法竞。
- 如果起點(diǎn)路徑為一個不以“/”字符結(jié)尾的根目錄且參考路徑為相對路徑耙厚,則返回路徑為:起點(diǎn)路徑+“/”+參考路徑中去除開頭的“./”字符或“../”字符(如果存在的話)后的文字。如果起點(diǎn)路徑為一個以“/”字符結(jié)尾的根目錄且參考路徑為相對路徑岔霸,則返回起點(diǎn)路徑+參考路徑中去除開頭的“./”字符或“../”字符(如果存在的話)后的文字薛躬。
- 如果起點(diǎn)路徑為一個不以“/”字符結(jié)尾的子目錄且參考路徑為相對路徑,同時開頭字符不為“./”或“../”呆细,則返回路徑為:起點(diǎn)路徑的上層目錄+“/”+參考路徑型宝。如果起點(diǎn)路徑為一個以“/”字符結(jié)尾的子目錄且參考路徑為相對路徑,同時開頭字符不為“./”或“../”絮爷,則返回路徑為:起點(diǎn)路徑的上層目錄+“/”+參考路徑趴酣。
- 如果起點(diǎn)路徑為一個不以“/”字符結(jié)尾的子目錄且參考路徑為相對路徑,同時開頭字符為“./”坑夯,則返回路徑為:起點(diǎn)路徑的上層目錄+“/”+參考路徑中去除開頭的“./”字符后的文字岖寞。如果起點(diǎn)路徑為一個以“/”字符結(jié)尾的子目錄且參考路徑為相對路徑,同時開頭字符為“./”柜蜈,則返回起點(diǎn)路徑+參考路徑中去除開頭的“./”字符后的文字仗谆。
- 如果起點(diǎn)路徑為一個不以“/”字符結(jié)尾的子目錄且參考路徑為相對路徑,同時開頭字符為“../”淑履,則返回路徑為:起點(diǎn)路徑的上層目錄的上層目錄+“/”+參考路徑中去除開頭的“../”字符后的文字隶垮。如果起點(diǎn)路徑為一個以“/”字符結(jié)尾的子目錄且參考路徑為相對路徑,同時開頭字符為“../”秘噪,則返
回起點(diǎn)路徑的上層目錄+參考路徑中去除開頭的“../”字符后的文字狸吞。