1. 程式人生 > >nodejs學習筆記(五)——處理get和post請求

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"&params2=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"&params2=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安全協議等等)。