Node.js-請求響應原理及HTTP協議

一、 服務器端基礎概念

1 網站的組成
網站應用程序主要分爲兩大部分:客戶端和服務器端。
客戶端:在瀏覽器中運行的部分,就是用戶看到並與之交互的界面程序。使用HTML、CSS、JavaScript構建。
服務器端:在服務器中運行的部分,負責存儲數據和處理應用邏輯。
在這裏插入圖片描述
在這裏插入圖片描述

2 Node網站服務器
能夠提供網站訪問服務的機器就是網站服務器,它能夠接收客戶端的 請求 ,能夠對請求做出 響應
在這裏插入圖片描述 在這裏插入圖片描述

3 IP地址
互聯網中設備的唯一標識。
IP是Internet Protocol Address的簡寫,代表互聯網協議地址.
在這裏插入圖片描述

4 域名
由於IP地址難於記憶,所以產生了域名的概念,所謂域名就是平時 上網所使用的網址
http://www.baidu.com => http://119.75.217.109/
雖然在地址欄中輸入的是網址, 但是最終還是會將域名轉換爲ip才能訪問到指定的網站服務器。

5 端口
端口是計算機與外界通訊交流的出口,用來區分服務器電腦中提供的不同的服務。
在這裏插入圖片描述在這裏插入圖片描述
6 URL
統一資源定位符,又叫URL(Uniform Resource Locator),是專爲標識Internet網上資源位置而設的一種編址方式,我們平時所說的網頁地址指的即是URL。
URL的組成
傳輸協議😕/服務器IP或域名:端口/資源所在位置標識
https://www.baidu.com/s?wd=node
http:超文本傳輸協議,提供了一種發佈和接收HTML頁面的方法。

7 開發過程中客戶端和服務器端說明
在開發階段,客戶端和服務器端使用同一臺電腦,即開發人員電腦。
在這裏插入圖片描述
在這裏插入圖片描述

二、 創建web服務器

創建web服務器

  // 引用系統模塊
 const http = require('http');
  // 創建web服務器
 const app = http.createServer();
  // 當客戶端發送請求的時候
 app.on('request', (req, res) => {
        //  響應
       res.end('<h1>hi, user</h1>');
 });
  // 監聽3000端口
 app.listen(3000);
 console.log('服務器已啓動,監聽3000端口,請訪問 localhost:3000')

三、 HTTP協議

1 HTTP協議的概念
超文本傳輸協議(英文:HyperText Transfer Protocol,縮寫:HTTP)規定了如何從網站服務器傳輸超文本到本地瀏覽器,它基於客戶端服務器架構工作,是客戶端(用戶)和服務器端(網站)請求和應答的標準。
在這裏插入圖片描述

2 報文
在HTTP請求和響應的過程中傳遞的數據塊就叫報文,包括要傳送的數據和一些附加信息,並且要遵守規定好的格式。
在這裏插入圖片描述

3 請求報文
① 請求方式 (Request Method)

  • GET 請求數據
  • POST 發送數據

② 請求地址 (Request URL)

 app.on('request', (req, res) => {
     req.headers  // 獲取請求報文
     req.url      // 獲取請求地址
     req.method   // 獲取請求方法
 });

4 響應報文
① HTTP狀態碼

  • 200 請求成功
  • 404 請求的資源沒有被找到
  • 500 服務器端錯誤
  • 400 客戶端請求有語法錯誤
    ② 內容類型
  • text/html
  • text/css
  • application/javascript
  • image/jpeg
  • application/json
    在這裏插入圖片描述

四、HTTP請求與響應處理

1 請求參數
客戶端向服務器端發送請求時,有時需要攜帶一些客戶信息,客戶信息需要通過請求參數的形式傳遞到服務器端,比如登錄操作。
在這裏插入圖片描述在這裏插入圖片描述

2 GET請求參數

  • 參數被放置在瀏覽器地址欄中,例如:http://localhost:3000/?name=zhangsan&age=20
  • 參數獲取需要藉助系統模塊url,url模塊用來處理url地址
 const http = require('http');
 // 導入url系統模塊 用於處理url地址
 const url = require('url');
 const app = http.createServer();
 app.on('request', (req, res) => {
     // 將url路徑的各個部分解析出來並返回對象
         // true 代表將參數解析爲對象格式
     let {query} = url.parse(req.url, true);
     console.log(query);
 });
 app.listen(3000);

3 POST請求參數

  • 參數被放置在請求體中進行傳輸
  • 獲取POST參數需要使用data事件和end事件
  • 使用querystring系統模塊將參數轉換爲對象格式
 // 導入系統模塊querystring 用於將HTTP參數轉換爲對象格式
 const querystring = require('querystring');
 app.on('request', (req, res) => {
     let postData = '';
     // 監聽參數傳輸事件
     req.on('data', (chunk) => postData += chunk;);
     // 監聽參數傳輸完畢事件
     req.on('end', () => { 
         console.log(querystring.parse(postData)); 
     }); 
 });

4 路由
http://localhost:3000/index
http://localhost:3000/login
路由是指客戶端請求地址與服務器端程序代碼的對應關係。簡單的說,就是請求什麼響應什麼。
// 當客戶端發來請求的時候
在這裏插入圖片描述

 app.on('request', (req, res) => {
     // 獲取客戶端的請求路徑
     let { pathname } = url.parse(req.url);
     if (pathname == '/' || pathname == '/index') {
         res.end('歡迎來到首頁');
     } else if (pathname == '/list') {
         res.end('歡迎來到列表頁頁');
     } else {
        res.end('抱歉, 您訪問的頁面出遊了');
     }
 });

5 靜態資源
服務器端不需要處理,可以直接響應給客戶端的資源就是靜態資源,例如CSS、JavaScript、image文件。
http://www.xxNode.cn/images/logo.png
在這裏插入圖片描述

6 動態資源
相同的請求地址不同的響應資源,這種資源就是動態資源。
http://www.xxnode.cn/article?id=1
http://www.xxnode.cn/article?id=2
在這裏插入圖片描述

7 客戶端請求途徑
① GET方式

  • 瀏覽器地址欄
  • link標籤的href屬性
  • script標籤的src屬性
  • img標籤的src屬性
  • Form表單提交
    ② POST方式
  • Form表單提交
    在這裏插入圖片描述

五、Node.js異步編程

 // 路徑拼接
 const public = path.join(__dirname, 'public');
 // 請求地址解析
 const urlObj = url.parse(req.url);
 // 讀取文件
 fs.readFile('./demo.txt', 'utf8', (err, result) => {
     console.log(result);
 });

1 同步 API,異步 API
同步API:只有當前API執行完成後,才能繼續執行下一個API

console.log('before'); 
console.log('after');

異步API:當前API的執行不會阻塞後續代碼的執行

console.log('before');
setTimeout(
   () => { console.log('last');
}, 2000);
console.log('after');

2 同步API, 異步API的區別( 獲取返回值 )

同步API可以從返回值中拿到API執行的結果, 但是異步API是不可以的

   // 同步
  function sum (n1, n2) { 
      return n1 + n2;
  } 
  const result = sum (10, 20);
    // 異步
  function getMsg () { 
      setTimeout(function () { 
          return { msg: 'Hello Node.js' }
      }, 2000);
  }
  const msg = getMsg ();

3 回調函數
自己定義函數讓別人去調用。

  // getData函數定義
 function getData (callback) {}
  // getData函數調用
 getData (() => {});

4 使用回調函數獲取異步API執行結果

function getMsg (callback) {
    setTimeout(function () {
        callback ({ msg: 'Hello Node.js' })
    }, 2000);
}
getMsg (function (msg) { 
    console.log(msg);
});

5 同步API, 異步API的區別(代碼執行順序)
同步API從上到下依次執行,前面代碼會阻塞後面代碼的執行

for (var i = 0; i < 100000; i++) { 
    console.log(i);
}
console.log('for循環後面的代碼');

異步API不會等待API執行完成後再向下執行代碼

console.log('代碼開始執行'); 
setTimeout(() => { console.log('2秒後執行的代碼')}, 2000);
setTimeout(() => { console.log('"0秒"後執行的代碼')}, 0); 
console.log('代碼結束執行');

6 代碼執行順序分析

console.log('代碼開始執行');
setTimeout(() => {
    console.log('2秒後執行的代碼');
}, 2000); 
setTimeout(() => {
    console.log('"0秒"後執行的代碼');
}, 0);
console.log('代碼結束執行');

在這裏插入圖片描述

7 Node.js中的異步API

 fs.readFile('./demo.txt', (err, result) => {});
 var server = http.createServer();
 server.on('request', (req, res) => {});

如果異步API後面代碼的執行依賴當前異步API的執行結果,但實際上後續代碼在執行的時候異步API還沒有返回結果,這個問題要怎麼解決呢?

fs.readFile('./demo.txt', (err, result) => {});
console.log('文件讀取結果');

需求:依次讀取A文件、B文件、C文件

8 Promise
Promise出現的目的是解決Node.js異步編程中回調地獄的問題。

let promise = new Promise((resolve, reject) => {
    setTimeout(() => {
        if (true) {
            resolve({name: '張三'})
        }else {
            reject('失敗了') 
        } 
    }, 2000);
});
promise.then(result => console.log(result); // {name: '張三'})
       .catch(error => console.log(error); // 失敗了)

9 異步函數
異步函數是異步編程語法的終極解決方案,它可以讓我們將異步代碼寫成同步的形式,讓代碼不再有回調函數嵌套,使代碼變得清晰明瞭。

const fn = async () => {};
async function fn () {}

async關鍵字

  1. 普通函數定義前加async關鍵字 普通函數變成異步函數
  2. 異步函數默認返回promise對象
  3. 在異步函數內部使用return關鍵字進行結果返回 結果會被包裹的promise對象中 return關鍵字代替了resolve方法
  4. 在異步函數內部使用throw關鍵字拋出程序異常
  5. 調用異步函數再鏈式調用then方法獲取異步函數執行結果
  6. 調用異步函數再鏈式調用catch方法獲取異步函數執行的錯誤信息
    await關鍵字
  7. await關鍵字只能出現在異步函數中
  8. await promise await後面只能寫promise對象 寫其他類型的API是不不可以的
  9. await關鍵字可是暫停異步函數向下執行 直到promise返回結果
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章