nodejs學習筆記(五)——處理get和post請求
上一章介紹瞭如何在nodejs中構造httpserver以及在nodejs中如何構造httpclient來訪問httpserver,接下來說一下nodejs在http互動中是如何處理請求的。首先我們回顧一下上一章最後的例子:
server程式碼(server把請求頭資訊處理後作為響應訊息返回給client):
var http = require('http'); var url = require('url'); var util = require('util'); http.createServer(function (request, response) { // 傳送 HTTP 頭部 // HTTP 狀態值: 200 : OK // 內容型別: text/plain response.writeHead(200, {'Content-Type': 'text/plain'}); // 傳送響應資料 "Hello World" //response.end('Hello World\n'); response.end(util.inspect(url.parse(request.url, true))); }).listen(8888); // 終端列印如下資訊 console.log('Server running at http://127.0.0.1:8888/');
把server程式碼儲存在在test8.js中,然後通過node test8.js命令來啟動httpserver(如果之前已經啟動,則需要停止以後再啟動,截圖略)。
client程式碼:
var http = require('http'); // 用於請求的選項 var options = { host: 'localhost', port: '8888', path: '/test?params1="123"¶ms2=456' }; // 處理響應的回撥函式 var callback = function(response){ // 不斷更新資料 var body = ''; response.on('data', function(data) { body += data; }); response.on('end', function() { // 資料接收完成 console.log(body); }); } // 向服務端傳送請求 var req = http.request(options, callback); req.end();
把client程式碼儲存在在test9.js中,然後另開一個命令列視窗通過node test9.js命令來啟動httpclient並訪問httpserver(如果之前已經啟動,則需要停止以後再啟動):
client程式碼並沒有顯式地表達自己傳送的是get請求還是post請求,但是通常情況下應該是預設傳送get請求,下面我們來看一下http.request函式的引數描述:
可以看到在引數options裡有一個method屬性,預設值為get,這個屬性確定了client傳送的是get請求還是post請求。OK,目前我們可以確認client傳送的get請求,再檢查一下server程式碼是怎麼處理client的請求資訊:
上一章的例子裡變更了client的請求路徑(options裡的path),server一樣可以正常響應,下面來嘗試變更client的請求方式,來驗證server是否同樣不感知,以下是client程式碼:
var http = require('http');
// 用於請求的選項
var options = {
host: 'localhost',
port: '8888',
path: '/test?params1="123"¶ms2=456' ,
method: 'POST'
};
// 處理響應的回撥函式
var callback = function(response){
// 不斷更新資料
var body = '';
response.on('data', function(data) {
body += data;
});
response.on('end', function() {
// 資料接收完成
console.log(body);
});
}
// 向服務端傳送請求
var req = http.request(options, callback);
//構造post訊息體
data = {user:"hello",password:"world"};
req.write(require('querystring').stringify(data));
req.end();
以下為變更說明:
把變更後的client程式碼儲存在在test9.js中,然後另開一個命令列視窗通過node test9.js命令來啟動httpclient並訪問httpserver(如果之前已經啟動,則需要停止以後再啟動):
可以看到請求依然正常得到了響應,這也證明了上例的server並不感知任何client傳送的資訊(不論是post訊息體、http頭還是url)。但是在實際的專案開發中,一個不能感知請求詳情的server並沒有什麼卵用,接下來給出一個說明server如何讀取client傳送資訊的例子:
var http = require('http');
var url = require('url');
var util = require('util');
http.createServer(function (request, response) {
console.log(request.method);
if(request.method == "GET"){
console.log("enter GET");
}else{
var postdata = "";
request.on("data",function(postchunk){
postdata += postchunk;
});
request.on("end",function(){
console.log(postdata);
});
}
// 傳送 HTTP 頭部
// HTTP 狀態值: 200 : OK
// 內容型別: text/plain
response.writeHead(200, {'Content-Type': 'text/plain'});
// 傳送響應資料 "Hello World"
//response.end('Hello World\n');
response.end(util.inspect(url.parse(request.url, true)));
}).listen(8888);
// 終端列印如下資訊
console.log('Server running at http://127.0.0.1:8888/');
以下為變更說明:
把變更的server程式碼儲存在在test8.js中,然後通過node test8.js命令來啟動httpserver(如果之前已經啟動,則需要停止以後再啟動),再另開一個命令列視窗通過node test9.js命令來啟動httpclient並訪問httpserver(如果之前已經啟動,則需要停止以後再啟動),下面看一下server的列印資訊:
可以看到server正常列印了請求型別以及post請求的訊息體(由於client未宣告post訊息體資料型別,預設是按字串處理,所以雖然在client側訊息體是一個json,但在server側列印的接收到的post訊息體是一個字串)。
實際上只要能夠明確請求型別和請求url(對應url物件的path,即請求路徑),即可確定一個server端提供的介面(通常介面文件都是依據這兩個資訊來區分不同的介面),而請求資訊的獲取和操作則屬於業務行為。post訊息體的獲取和使用屬於純業務操作(與介面無關,介面定義不care資料該如何獲取和獲取到的資料該如何使用),而http頭的獲取和使用則涉及安全(如sessionid、tls安全協議等等)。