NodeJs 入門到放棄 — 網路伺服器(三)

Echoyya、發表於2021-03-05

碼文不易啊,轉載請帶上本文連結呀,感謝感謝 https://www.cnblogs.com/echoyya/p/14484454.html

http (協議)

網路是資訊傳輸、接收、共享的虛擬平臺,而網路傳輸資料有一定的規則,稱協議,而HTTP協議就是其中之一,且使用最為頻繁。

定義、約束、互動特點、工作原理

定義:HTTP 即 超文字傳輸協議,是一種網路傳輸協議,採用的是請求 / 響應方式傳遞資料,該協議規定了資料在伺服器與瀏覽器之間,傳輸資料的格式與過程

約束:

  1. 約束了瀏覽器以何種格式兩伺服器傳送資料

  2. 約束了伺服器以何種格式接收客戶端傳送的資料

  3. 約束了伺服器以何種格式響應資料給瀏覽器

  4. 約束了以何種格式接收伺服器響應的資料

互動特點:

  1. HTTP是無連線:無連線的含義是一次請求對應一次響應,限制每次連線只處理一個請求。伺服器處理完客戶端的請求,並收到客戶端的應答後,即斷開連線。採用這種方式可以節省傳輸時間。
  2. HTTP是媒體獨立的:只要客戶端和伺服器知道如何處理的資料內容,任何型別的資料都可以通過HTTP傳送。客戶端以及伺服器指定使用適合的MIME-type型別。

工作原理:

在瀏覽器位址列中輸入網址,將網址傳送DNS伺服器進行域名解析,獲取對應的IP地址,3次握手,瀏覽器與目標伺服器建立TCP連線併發起請求,伺服器處理請求發出響應,瀏覽器解析htm程式碼,對頁面進行渲染呈現給使用者。

上述內容也是一道常見的面試題:瀏覽器輸入地址後發生了什麼

狀態碼

向伺服器發出請求,此網頁所在的伺服器會返回一個HTTP狀態碼,用以響應瀏覽器的請求。

常見的狀態碼:

  • 200 - 請求成功
  • 301 - 資源被永久轉移到其它URL
  • 404 - 請求的資源不存在
  • 500 - 內部伺服器錯誤

MIME 型別

檔案型別的一種表述,用於標識檔案型別。

常見MIME型別:

  • text/html : .html
  • text/plain :純文字
  • text/xml : xml
  • image/gif :.gif
  • image/jpeg :.jpg
  • image/png:.png

http (模組)

http模組是nodejs中系統模組,用於網路通訊,可以作為客戶端傳送請求,亦可以作為伺服器端處理響應

作為客戶端傳送請求

由於大多數請求都是不帶請求體的 GET 請求,因此最最最常用的方法:

  • http.get(url[, options][, callback])

    var http = require('http')
    var fs = require('fs')
    
    http.get('http://www.baidu.com/',function(res){
      // console.log(res);   
      // res 返回的即為一個可讀流, 
      res.pipe(fs.createWriteStream('./a.html'))
    })
    

作為伺服器處理響應

實現一個簡易伺服器步驟:

  1. 引入http通訊模組

  2. 建立伺服器物件

  3. 監聽 request 事件接收客戶端請求

  4. 監聽埠實現伺服器功能

  5. 訪問瀏覽器 127.0.0.1 或 localhost 或 區域網IP

var http = require('http')

// 建立伺服器
var server = http.createServer()

// 監聽request事件,請求發生返回資料,請求一次執行一次
server.on('request',function(req,res){
  // req:請求物件,包含所有客戶端請求的資料,請求頭,請求體
  // res:響應物件,包含所有伺服器響應的資料,響應頭,響應體

  // 設定響應頭 檔案型別及字元編碼
  res.writeHead(200, {'Content-Type': 'text/html; charset=utf-8'}); 

  res.write('<h1 style="color:red">歡迎訪問 nodejs</h1>')
  res.end()  // 伺服器結束響應
})

// 監聽伺服器80埠,預設就是80
server.listen('80',function(){
  console.log('Server is running....');
})

客戶端向伺服器端傳遞資料

  1. GET 方式:GET請求直接被嵌入在路徑中,URL是完整的請求路徑,包括了?後面的部分,可以解析後面的內容作為GET請求的引數。且url 模組中的 parse 函式提供了這個功能。

    啟動服務訪問:http://127.0.0.1:3000/?name=Echoyya&city=BeiJing

var http = require('http');
var url = require('url');
 
http.createServer(function(req, res){
    res.writeHead(200, {'Content-Type': 'text/html; charset=utf-8'});
 
    // 解析 url 引數
    var params = url.parse(req.url, true).query;
    res.write("姓名:" + params.name);
    res.write("城市:" + params.city);
    res.end();

}).listen(3000);

  1. POST 方式:POST 請求的內容全部都在請求體中,http.ServerRequest 並沒有一個屬性為請求體, node.js 預設是不會解析請求體的,需要手動來做。

    啟動服務訪問:http://127.0.0.1:3000/

var http = require('http');
var querystring = require('querystring');
 
var postHTML = 
  '<html><head><meta charset="utf-8"><title>POST</title></head>' +
  '<body>' +
  '<form method="post">' +
  '姓名: <input name="name"><br>' +
  '城市: <input name="city"><br>' +
  '<input type="submit">' +
  '</form>' +
  '</body></html>';
 
http.createServer(function (req, res) {
  // 定義了一個post變數,用於暫存請求體的資訊
  var post = "";
  req.on('data', function (chunk) {
    // 通過req的data事件監聽函式,每當接受到請求體的資料,就累加到 post 變數中
    post += chunk;
  });
  // 觸發end事件,通過querystring.parse將post解析為真正的POST請求格式,然後向客戶端返回。
  req.on('end', function () {
    post = querystring.parse(post);   // 解析引數
    // 設定響應頭部資訊及編碼
    res.writeHead(200, {'Content-Type': 'text/html; charset=utf8'});
 
    if(post.name && post.city) {  // 輸出提交的資料
        res.write("姓名:" + post.name);
        res.write("<br>");
        res.write("城市:" + post.city);
    } else {   // 輸出表單
        res.write(postHTML);
    }
    res.end();
  });
}).listen(3000);

網頁模板

首先區分兩個概念:

靜態網頁:標準的HTML檔案,可以包含文字,影像、聲音、動畫等,沒有後臺資料庫、不可互動的網頁。但可以出現各種動態的效果,如GIF動畫、滾動字幕等。靜態網頁相對更新起來比較麻煩。

動態網頁:是指跟靜態網頁相對的一種網頁程式設計技術。頁面程式碼雖然沒有變,但是顯示的內容卻是可以隨著時間、引數、環境或者資料庫操作的結果而發生改變。

動態網頁模板

動態獲取訪問者客戶端的IP,輸出到網頁:

var http = require('http');

http.createServer(function (req, res) {
  var ip = req.socket.remoteAddress;
  res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' });
  res.write("<h1>你的IP地址是:"+ ip +"</h1>");
  res.end()
}).listen(80);

每個客戶端請求的IP都不一樣,可以使用資料拼接的方式,可以達到動態輸出網頁的效果,但輸出給瀏覽的並非是一個完整的網頁,實際上完整的網頁程式碼要多得多。

網頁模板工作原理:把一些靜態固定的內容,儲存為靜態檔案,動態內容寫成 模板語法,在使用模板引擎讀取該檔案,進行內容替換,最終實現一個動態頁面,以下模擬操作:

index.html:使用模板語法,動態獲取訪問者客戶端的IP

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Home</title>
</head>
<body>
  <h1>你的IP地址是:<%=ip%></h1>
</body>
</html>

template.js:啟動服務訪問:http://127.0.0.1 或本地區域網IP 或 本地可解析域名地址

var http = require('http');
var fs = require('fs');

http.createServer(function (req, res) {
  
  res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' });
  
  var ip = req.socket.remoteAddress;
  fs.readFile('./index.html',function(err,chunk){
    res.write( render(chunk.toString(),ip) )
    res.end();
  })

}).listen(80);

// 思想: 定義一個render 函式,用於將資料和html進行整合
function render(htmlStr,data){
   return htmlStr.replace('<%=ip%>',data)
}

相關文章