先給各位打個預防針,這篇博客比較長需要各位靜下心來看。同時這片博客也是最重要的1個環節。服務和客戶真個要求響應方式
Node.js 標準庫提供了 http 模塊,其中封裝了1個高效的 HTTP 服務器和1個簡易的HTTP客戶端。http.Server 是1個基于事件的 HTTP服務器,它的核心由 Node.js 下層 C++部份實現,而接口由 JavaScript 封裝,統籌了高性能與簡易性。 http.request 則是1個HTTP 客戶端工具,用于向 HTTP 服務器發起要求,例照實現 Pingback或內容抓取。
http.Server 是 http 模塊中的 HTTP 服務器對象,用Node.js 做的所有基于 HTTP 協議的系統,如網站、社交利用乃至代理服務器,都是基于 http.Server 實現的。它提供了1套封裝級別很低的 API,僅僅是流控制和簡單的消息解析,所有的高層功能都要通過它的接口來實現。
1、request:當客戶端要求到來時,該事件被觸發,提供兩個參數 req 和res,分別是http.ServerRequest 和 http.ServerResponse 的實例,表示要求和響應信息。
2、connection:當 TCP 連接建立時,該事件被觸發,提供1個參數 socket,為net.Socket 的實例。 connection 事件的粒度要大于 request,由于客戶端在Keep-Alive 模式下可能會在同1個連接內發送屢次要求。
3、close :當服務器關閉時,該事件被觸發。注意不是在用戶連接斷開時。
除此以外還有 checkContinue、 upgrade、 clientError 事件,通常我們不需要關心,只有在實現復雜的 HTTP 服務器的時候才會用到。
還記得我們之前是怎樣寫服務了嗎?http.createServer(fn)fn有兩個參數分別是req和resp最后有監聽端口號為3000的服務器。事實上我們創建服務還有1種顯示實現方法。
例如:
介紹這里我們就繼續深入這個服務咯
http.ServerRequest 是 HTTP 要求的信息。也是我們服務端最關心的內容。我們上邊說了http.server有1個requiest。它1般有http.server的requiest事件發送,作為第1個參數,ServerRequest提供1些屬性以下:
complete 客戶端要求是不是已發送完成
httpVersion HTTP 協議版本,通常是 1.0 或 1.1
method HTTP 要求方法,如 GET、 POST、 PUT、 DELETE 等
url 原始的要求路徑,例如/static/image/x.jpg 或 /user?name=byvoid
headers HTTP 要求頭
trailers HTTP 要求尾(不常見)
connection 當前 HTTP 連接套接字,為 net.Socket 的實例
socket connection 屬性的別名
client client 屬性的別名
說了http。Serverrequest是http要求的信息了那httpp要求1般可以分兩部份的噢噢。1個要求頭1個要求體。作為要求體可能相對較長。但是我們要求不能等待好長時間啊,你受的了單用戶受不了啊!!,所以http。Serverquest提供了3個事件來供我們控制要求體傳輸噢噢。
1、 data :當要求體數據到來時,該事件被觸發。該事件提供1個參數 chunk,表示接收到的數據。如果該事件沒有被監聽,那末要求體將會被拋棄。該事件可能會被調用屢次。
2、 end :當要求體數據傳輸完成時,該事件被觸發,爾后將不會再有數據到來。
3、 close: 用戶當前要求結束時,該事件被觸發。不同于end,如果用戶強迫終止了傳輸,也還是調用close。
如果你是個開發人員就知道作為要求經常使用到的post和get兩個對吧。但是http.serverrequest不像其他的java和php都有get和post方法噢噢,在這里你就問我了,那nodejs怎樣做get要求呢?大家想一想由于get是嵌入到url中,包括了?后邊的部份,因此你可以手動解析后邊的內容作為get要求的參數啊。你要把參數轉化成對象,固然轉化部份node已為我們提供了parse模塊了。例如
上邊這段代碼我就新加了兩個方法util.inspect和url.parse第1個返回1個對象的字符串表現情勢,第2個就是把字符串轉發成json對象
在閱讀器訪問http://localhost:3000/user?name=’heimao’&age=23我們看下結果噢噢
Url {
protocol: null,
slashes: null,
auth: null,
host: null,
port: null,
hostname: null,
hash: null,
search:'?name=%27heimao%27&age=12',
query: { name:'\'heimao\'', age: '12' },
pathname: '/',
path:'/?name=%27heimao%27&age=12',
href:'/?name=%27heimao%27&age=12' }
接下來只是我們對字符串的處理咯鐺鐺當。。。。。。是否是很拽。query則是我們所謂的get要求的內容。而路徑則是pathname。
上邊我們介紹了get的要求方式。下邊我們要介紹下第2個post要求內容的獲得。還記得我上邊說的嗎http要求是分兩部份1個是要求頭1個是要求體。HTTP協議 1.1 版本提供了8種標準的要求方法,其中最多見的就是 GET 和 POST。Get我們就不說了就是將內容編碼到url中。Post要求內容全部都在要求體中。http.serverrequest則沒有1個要求體的屬性。其緣由是等待要求體傳輸是個耗時的工作。客戶會受不了的。所以為了解決這個問題,Node是不會自己解析要求體的。當你需要的時候需要我們自己手動的去解析它。來看看示例我們將要如何解析post過來的要求體。
通過上邊的代碼我們可以知道node并沒有解析post要求過來的數據,而是通過chunk參數把數據緩存到了post變量里邊最后通過觸發end事件后通過queryString.Parse將post解析為真實的post要求格式。然后返回客戶端。
回顧我們上邊說的,我們只是說了下3個重要點1個是http.request的事件包括data,end,connect。還有rquest的經常使用的兩個方法post和get的解析方式。當我們把要求的兩種方法說完以后該說http.serverresponse響應方式了.
http.ServerResponse 是返回給客戶真個信息,決定了用戶終究能看到的結果。它也是由 http.Server 的 request 事件發送的,作為第2個參數傳遞,1般簡稱為response 或 res
http.serverresponse有3個重要的成員函數,用于返回響應頭,響應內容和結束要求。
1、response.writeHead(statusCode, [headers]):向要求的客戶端發送響應頭。statusCode 是 HTTP 狀態碼,如 200 (要求成功)、 404 (未找到)等。 headers是1個類似關聯數組的對象,表示響應頭的每一個屬性。該函數在1個要求內最多只能調用1次,如果不調用,則會自動生成1個響應頭。
2、response.write(data, [encoding]):向要求的客戶端發送響應內容。 data 是1個 Buffer 或字符串,表示要發送的內容。如果 data 是字符串,那末需要指定encoding 來講明它的編碼方式,默許是 utf⑻。在 response.end 調用之前,response.write 可以被屢次調用。
3、response.end([data], [encoding]):結束響應,告知客戶端所有發送已完成。當所有要返回的內容發送終了的時候,該函數必須 被調用1次。它接受兩個可選參數,意義和 response.write 相同。如果不調用該函數,客戶端將永久處于等待狀態。
說完了服務端所需的操作方法我們接下來就該了解客戶真個1些方法了,接下來來看下我們客戶端所需要的方法都有哪些、
http模塊為客戶端提供了兩個方法1個request和1個get,功能是作為客戶端向http服務器發起要求。
1、http.request(options,callback)發起1個http要求,接受兩個參數,option是1個關聯數組的對象,表示要求參數,callback是要求的回調函數。
Option的詳細配置項以下:
1) host :要求網站的域名或 IP 地址
2) port :要求網站的端口,默許80。
3) method :要求方法,默許是 GET。
4) path :要求的相對根的路徑,默許是“ /”。 QueryString 應當包括在其中。例如search?query=byvoid。
5) headers :1個關聯數組對象,為要求頭的內容。
6) callback 傳遞1個參數,為http.ClientResponse 的實例
7)
而http.request返回的是1個http.clientRequest的實例
下邊是通過http.request發送post要求的代碼
運行后結果以下:
array(3){
["name"]=>
string(6) "heimao"
["email"]=>
string(14) "heimao@126.com"
["address"]=>
string(10) "河北邯鄲那"
}
固然除客戶端用post要求也能夠用get要求的,也能夠把option內的method方法寫成get,但是呢node已為我們準備了更簡單的get要求方法。以下:
2、http.get(options,callback):它是 http.request 的簡化版,唯1的區分在于http.get自動將要求方法設為了 GET 要求,同時不需要手動調用 req.end()
固然除描寫get方法我還得寫個簡單的demo更容易理解:demo以下:
我們在上邊分別介紹了客戶真個post和get要求,但是里邊回調函數的參數和返回的對象還是有必要要跟大家說下,我們首先介紹下get和post返回的對象http。clientRequest。
http.ClientRequest 是由 http.request 或 http.get 返回產生的對象,表示1個已產生而且正在進行中的 HTTP要求。它提供1個 response 事件,即 http.request或 http.get 第2個參數指定的回調函數的綁定對象。我們也能夠顯式地綁定這個事件的監聽函數:
var http =require('http');
var req =http.get({host: 'www.byvoid.com'});
req.on('response', function(res) {
res.setEncoding('utf8');
res.on('data', function (data) {
console.log(data);
});
});
http.ClientRequest 像 http.ServerResponse1樣也提供了 write 和 end 函數,用于向服務器發送要求體,通經常使用于 POST、 PUT 等操作。所有寫結束以后必須調用 end函數以通知服務器,否則要求無效。 http.ClientRequest 還提供了以下函數
1. request.abort():終止正在發送的要求。
2. request.setTimeout(timeout, [callback]):設置要求超時時間,timeout 為毫秒數。當要求超時以后, callback 將會被調用。
3. 另外還有request.setNoDelay([noDelay])、request.setSocketKeepAlive([enable], [initialDelay]) 等函數,具體內容請參見Node.js 文檔。
介紹完了http.get()和http.Request返回clientrequest的對象以后我們再說下http.get和http.Request的第2個參數回調函數的參數http.clientResponse
clientResponse與服務真個http.serverrequest相似,提供了3個事件date,end和close,分別是數據到達,傳輸結束和連接結束時觸發,其中data事件傳遞1個參數chunk,表示接遭到的數據。
http.ClientResponse也提供了1些屬性,用于表示要求的結果狀態,
1) statusCode: HTTP 狀態碼,如 200、 404、 500
2) httpVersion: HTTP 協議版本,通常是 1.0 或 1.1
3) headers: HTTP 要求頭
4) trailers: HTTP 要求尾(不常見)
除以上幾個屬性以外還停工了幾個特殊的函數以下
1) response.setEncoding([encoding]):設置默許的編碼,當data 事件被觸發時,數據將會以 encoding 編碼。默許值是 null,即不編碼,以 Buffer 的情勢存儲。經常使用編碼為 utf8。
2) response.pause():暫停接收數據和發送事件,方便實現下載功能。
3) response.resume():從暫停的狀態中恢復。
更多的參考資料地址:
Node.js Manual & Documentation:http://nodejs.org/api/index.html。
Understanding process.nextTick():http://howtonode.org/understanding- processnext-tick。
揭秘Node.js事件: http://www.grati.org/?p=318