在Node.js中底挫,提供了http模塊與https模塊汉操,專用于創(chuàng)建HTTP服務(wù)器,HTTP客戶端奔穿,以及HTTPS服務(wù)器和HTTPS客戶端,同事實現(xiàn)這些服務(wù)器端與客戶端之中所需要進(jìn)行的處理敏晤。
http服務(wù)器
引用http模塊,調(diào)用http模塊中的createServer方法,在createServer的回調(diào)函數(shù)中處理用戶請求
創(chuàng)建http服務(wù)器
var http = require('http');
// 調(diào)用http模塊中的createServer方法
// 在createServer的回調(diào)函數(shù)中處理用戶請求
var server = http.createServer(function(req,res){
// 第一個參數(shù)是客戶端的請求對象贱田,
// 第二個參叔代表服務(wù)器相應(yīng)對象
// 接受客戶端請求時的其他他處理
});
server.listen(3000,"127.0.0.1");
request事件
// 可以監(jiān)聽http.createServer方法創(chuàng)建的服務(wù)器對象的request時間
// request表示接受到客戶端請求時所需要處理
server.on('request',function(request,response){
// 第一個參數(shù)是客戶端的請求對象,
// 第二個參叔代表服務(wù)器相應(yīng)對象
console.log('')
})
listening事件
// 當(dāng)對http服務(wù)器指定了需要監(jiān)聽的地址和端口后嘴脾,服務(wù)器將立即開始監(jiān)
// 聽來自改地址及端口的客戶端鏈接男摧,這時觸發(fā)該服務(wù)器的listening事件
// 可以通過監(jiān)聽http服務(wù)器對象的listening事件,并且指定該時間觸發(fā)時
// 調(diào)用的回調(diào)函數(shù)的方法來指定http服務(wù)器開始監(jiān)聽時所需執(zhí)行的處理
server.on('listening',function(){
// 回調(diào)函數(shù)為可選參數(shù)
console.log('服務(wù)器端開始監(jiān)聽')
});
close事件
// 這段代碼中由于沒有關(guān)閉http服務(wù)器译打,因此該服務(wù)器將一直監(jiān)聽來自于
// 指定地址及端口的客戶端鏈接耗拓,應(yīng)用程序?qū)⒉粫顺觯?dāng)http服務(wù)器被關(guān)閉時
// 如果服務(wù)器尚未與任何客戶端建立鏈接奏司,應(yīng)用程序?qū)⒄M顺觥?// 當(dāng)http服務(wù)器被關(guān)閉后乔询,將不再接受來自listen方法中指定的地址及端口號
// 的客戶端鏈接。
// 可以使用客戶端的close方法關(guān)閉該服務(wù)器
server.on('close',function(){
// 回調(diào)函數(shù)為可選參數(shù)
console.log('服務(wù)器已關(guān)閉')
})
error事件
// 在對HTTP服務(wù)器指定需要監(jiān)聽的地址及端口時结澄,如果該地址及端口已被占用
// 將產(chǎn)生錯誤哥谷,觸發(fā)服務(wù)器的error事件,可以通過對error事件設(shè)置回調(diào)函數(shù)
// 的方法來指定該錯誤產(chǎn)生時所需要執(zhí)行的處理
server.on('error',function(e){
// 回調(diào)函數(shù)為可選參數(shù)
console.log(e)
console.log('服務(wù)器鏈接失敗')
})
connection事件
// 當(dāng)客戶端與服務(wù)器端建立鏈接時麻献,觸發(fā)http服務(wù)器對象 connection事件
// 可以監(jiān)聽該事件并在該事件觸發(fā)時調(diào)用的回調(diào)函數(shù)中指定當(dāng)連接建立時所需要
// 執(zhí)行的處理
server.on('connection',function(socket){
console.log('客戶端連接已建立')
})
// 客戶端會輸出兩次"客戶端連接已建立",這是因為在瀏覽器訪問http服務(wù)器時,
// 瀏覽器會發(fā)出兩次客戶端請求猜扮,一次是用戶發(fā)出的請求勉吻,另一次是瀏覽器為頁面在收藏夾
// 中顯示圖標(biāo)(favicon.ico)而自動發(fā)出的請求
timeOut事件
// 在node中,將http服務(wù)器的默認(rèn)超時時間設(shè)置為2分鐘
// 當(dāng)服務(wù)器超時時旅赢,觸發(fā)該服務(wù)器對象的timeout事件
server.on('timeout',function(socket){
// socket為服務(wù)器端用于監(jiān)聽客戶端請求的socket對象
})
setTimeout服務(wù)器超時事件
// 可以使用http服務(wù)器的setTimeout方法來設(shè)置服務(wù)器的超時時間
// 當(dāng)該超時時間超過之后齿桃,客戶端不可繼續(xù)利用本次與HTTP服務(wù)器建立鏈接
// 下次向該服務(wù)器發(fā)出請求時必須重新建立連接
server.setTimeout(60*1000,function(socket){
console.log('服務(wù)器超時')
})
console.log(server.timeout) //可以查看服務(wù)器的超時時間
獲取客戶端信息
如下
var http = require('http');
var fs = require('fs');
var server = http.createServer(function(req,res){
if(req.url !== '/favicon.ico'){
var out = fs.createWriteStream('./request.log');
out.write('客戶端請求方法'+req.method+'\r\n');
out.write('客戶端請求url'+req.url+'\r\n');
out.write('客戶端請求頭對象'+JSON.stringify(req.headers)+'\r\n');
out.end('客戶端請求所用http版本'+req.httpVersion)
}
res.end();
})
server.listen(3000,"127.0.0.1");
運(yùn)行代碼惑惶,在應(yīng)用程序的根目錄下將創(chuàng)建一個request.log文件,打開該文件短纵,顯示如下
轉(zhuǎn)換URL字符串與查詢字符串
在node中带污,提供了一個url模塊與Query String模塊,分別用來轉(zhuǎn)換完整URL字符串與URL中的查詢字符串香到。
querystring.parse(str, [sep], [eq], [opaction])
我們用的時候鱼冀,基本上后三個參數(shù)用默認(rèn)的就好
這樣當(dāng)我們參數(shù)為username=luckFine & age=14 & sex = boy
那么當(dāng)調(diào)用parse方法時querystring.parse(username=luckFine & age=14 & sex = boy)
結(jié)果就是
{
username : luckFine,
age : 14,
sex : boy
}
當(dāng)客戶端提交表單數(shù)據(jù)時,且表單中存在復(fù)選框時悠就,提交的查詢字符串存在類似username=luckFine & username=xiaoFan 這種形式的字符串千绪,在使用parse方法后,這種形式的字符串將轉(zhuǎn)化為對象中的一個數(shù)組梗脾。
{
username : [luckFine, xiaoFan],
age : 14,
sex : boy
}
反過來荸型,querystring.stringify(obj)
可以將對象轉(zhuǎn)化為一個查詢字符串,例如
querystring.stringify({username : luckFine,age : 14,
sex : boy})
那么運(yùn)行結(jié)果為 username=luckFine & age=14 & sex = boy
那么基于這個,在node中的url模塊炸茧,專門于對完整的URL字符串進(jìn)行轉(zhuǎn)換瑞妇。
在url模塊中可以使用parse方法將url字符串轉(zhuǎn)換為一個對象,根據(jù)URL字符串中的不同內(nèi)容梭冠,該對象中可能具有的屬性及含義如下
案例如下
相反踪宠,可以使用url模塊中的format方法將URL字符串經(jīng)過轉(zhuǎn)換后的對象還原為一個URL字符串。
url.format(urlObj)
我們看一下在http服務(wù)器中解析url字符串的代碼示例
var http = require('http');
var url = require('url');
var server = http.createServer(function(req,res){
if(req.url !== '/favicon.ico'){
res.write('<html><head><meta charset="utf-8"></head>')
var url_parts = url.parse(req.url);
switch (url_parts.pathname) {
case '/':
case '/index.html':
res.write('<body><h1>您正訪問的是首頁</h1></body></html>')
break;
default:
res.write('<body><h1>您正訪問的是'+url_parts.pathname+'</h1></body></html>')
break;
}
}
res.end();
})
server.listen(3000,"127.0.0.1");
發(fā)送服務(wù)器端響應(yīng)流
在發(fā)送請求的時候妈嘹,我們需要發(fā)送響應(yīng)頭
response.writeHead(statusCode,[reasonPhrase],[headers])
statusCode為一個三位的http狀態(tài)碼 例如200
reasonPhrase參數(shù)值為一個字符串柳琢,用于指定對于該狀態(tài)碼的描述信息
headers為一個對象,用于指定服務(wù)器創(chuàng)建的響應(yīng)頭對象
如下
var http = require('http');
var fs = require('fs');
var server = http.createServer(function(req,res){
if(req.url !== '/favicon.ico'){
res.writeHead(200,{'Content-Type':'text/plain;charset=UTF-8',
'Access-Control-Allow-Origin':'http://localhost'});
res.write("你好")
}
res.end();
})
server.listen(3000,"127.0.0.1");
也可以用http.ServerResponse對象的setHeader方法來設(shè)置響應(yīng)頭
var http = require('http');
var fs = require('fs');
var server = http.createServer(function(req,res){
if(req.url !== '/favicon.ico'){
res.setHeader('Content-Type','text/plain;charset=UTF-8');
res.setHeader('Access-Control-Allow-Origin','http://localhost');
res.write("你好ma")
}
res.end();
})
server.listen(3000,"127.0.0.1");
用setHeader設(shè)置響應(yīng)頭信息之后润脸,可以用getHeader獲取響應(yīng)頭的某個字段
response.getHeader(name)
或者用removeHeader(name) 移除某個響應(yīng)頭,但是用removeHeader(name)移除某個響應(yīng)頭的時候柬脸,必須在ServerResponse對象的write方法發(fā)送數(shù)據(jù)之前被調(diào)用。
通過示例來看響應(yīng)頭的發(fā)送時機(jī)
var http = require('http');
var server = http.createServer(function(req,res){
if(req.url !== '/favicon.ico'){
console.log(res.headersSent)
if(res.headersSent){
console.log('響應(yīng)頭已發(fā)送')
}else{
console.log('響應(yīng)頭未發(fā)送')
}
res.writeHeader(200,{'Content-Type':'text/html'});
if(res.headersSent){
console.log('響應(yīng)頭已發(fā)送0')
}else{
console.log('響應(yīng)頭未發(fā)送0')
}
res.write("你好")
}
res.end();
})
server.listen(3000,"127.0.0.1");
在使用setHeader方法時毙驯,當(dāng)http.ServerResponse對象的write方法被第一次調(diào)用時及發(fā)送響應(yīng)頭倒堕。
HTTP客戶端
在node中,可以用request任何網(wǎng)站發(fā)送請求并讀取該網(wǎng)站的相應(yīng)數(shù)據(jù)
向其他網(wǎng)站請求數(shù)據(jù)
假設(shè)我向百度請求數(shù)據(jù)
示例如下
var http = require('http');
// 設(shè)置請求信息
var options = {
hostname:'www.baidu.com',
post:80,
path:'/',
method:'GET'
};
var req = http.request(options,function(res){
console.log('狀態(tài)碼'+res.statusCode);
console.log('響應(yīng)頭'+JSON.stringify(res.headers));
// res.setEncoding() 用來指定用如何編碼該字符串
res.setEncoding('utf-8');
// 當(dāng)請求到數(shù)據(jù)的時候爆价,對數(shù)據(jù)進(jìn)行操作
res.on('data',function(chunk){
console.log('相應(yīng)內(nèi)容'+chunk)
})
// 當(dāng)請求超時調(diào)用req.setTimeout函數(shù)
req.setTimeout(1000,function(){
// req.about()終止本次請求
req.about();
})
// 當(dāng)請求失敗時垦巴,查看失敗原因
req.on('error',function(err){
console.log('請求數(shù)據(jù)發(fā)生錯誤,錯誤代碼'+err.code);
})
})
req.end();
由于請求結(jié)果過多铭段,那么我截取其中一小部分
同志們骤宣,點贊不花錢~給程序媛一個小谷粒噻