【進階篇】一文搞清楚網頁發起 HTTP 請求調用的完整過程

来源:https://www.cnblogs.com/CodeBlogMan/p/18249663
-Advertisement-
Play Games

最近筆者在實際項目開發中會頻繁涉及到服務之間的遠程調用、功能變數名稱的配置和請求的轉發等與電腦網路相關的知識。 這些其實在讀本科和考研的時候都有學習過理論,但為了更透徹地掌握便於在工作中使用,我還是決定寫一篇文章來分享實際開發中是怎麼應用的。 ...


目錄

前言

最近筆者在實際項目開發中會頻繁涉及到服務之間的遠程調用、功能變數名稱的配置和請求的轉發等與電腦網路相關的知識。

這些其實在讀本科和考研的時候都有學習過理論,但為了更透徹地掌握便於在工作中使用,我還是決定寫一篇文章來分享實際開發中是怎麼應用的。

下麵將從 HTTP 協議的基本概念與簡介、完整的請求過程、客戶端的請求以及服務端的響應這四部分來展開,同時會使用實際的場景來加以分析,便於大家理解。


一、HTTP協議

1.1基本概念

HTTP 協議(Hyper Text Transfer Protocol)超文本傳輸協議,即傳輸文字、圖片、音頻、視頻等超文本數據、是一種用於分散式、協作式和超媒體信息系統的應用層協議。為了更快地處理大量事務,確保協議的可伸縮性,HTTP 協議被設計成了一種無狀態協議,不保留之前一切的請求或響應報文的信息。HTTP 協議也是萬維網(WWW,World Wide Web)的數據通信的基礎。

HTTP 是一個客戶端(用戶)和伺服器端(網站)請求和應答的標準,其定義了定義 Web 客戶端如何向 Web 伺服器請求 Web 頁面,以及伺服器如何把 Web 頁面響應給客戶端。

HTTP 協議中並沒有規定必須使用 TCP/IP 或其支持的層。事實上,HTTP 可以在任何互聯網協議上,或其他網路上實現。HTTP 假定其下層協議提供可靠的傳輸。因此,任何能夠提供這種保證的協議都可以被其使用,所以其在 TCP/IP 協議族使用 TCP 作為其傳輸層,而 UDP 是不可靠傳輸。

用戶通過使用各種工具(如網頁瀏覽器、網路爬蟲或者 Jmeter 等)作為客戶端,來發起一個 HTTP 請求到伺服器的指定埠(預設為80)。這個客戶端被稱為用戶代理程式(User Agent)。而接受並響應該 HTTP 請求的伺服器上會存儲著各種用戶需要的資源,比如 HTML 文件和圖像,這個被用戶請求的伺服器被稱為源伺服器(Origin Server)

1.2工作原理

通常,由 HTTP 客戶端發起一個請求,創建一個到伺服器指定埠(預設是80埠)的 TCP 連接,HTTP伺服器則在那個埠監聽客戶端的請求。一旦收到請求,伺服器會向客戶端返回一個狀態,比如"HTTP/1.1 200 OK",以及響應請求而返回的內容,如文件、錯誤消息、或者其它數據等。

以下是 HTTP 協議工作流程的幾個關鍵步驟:

第一步:建立 TCP/IP 連接,客戶端與伺服器通過 Socket 三次握手進行連接

第二步:客戶端向服務端發起 HTTP 請求,如:POST/login.html http/1.1

第三步:客戶端發送請求頭部、請求內容,最後會發送一空白行,標示客戶端請求完畢

第四步:伺服器做出應答,表示對於客戶端請求的應答,如:HTTP/1.1 200 OK

第五步:伺服器向客戶端發送響應頭部信息,發送一空白行,表示應答頭信息發送完畢,隨後以 Content-type 要求的數據格式,發送響應正文給客戶端

第六步:服務端關閉 TCP 連接,如果伺服器或者客戶端的 Connection:keep-alive 則表示客戶端與伺服器端繼續保存連接,在下次請求時可以繼續使用這次的連接

二、請求過程

下麵對 1.2 小節中的幾個步驟做更為細緻的講解。

2.1功能變數名稱解析

瀏覽器向 DNS 伺服器請求解析該 URL 中的功能變數名稱所對應的 IP 地址,查找過程依次如下:

  1. 瀏覽器緩存

    首先搜索瀏覽器自身的 DNS 緩存(緩存的時間比較短,大概只有1分鐘,且只能容納1000條緩存),看自身的緩存中是否是有功能變數名稱對應且未過期的條目。如果有,則功能變數名稱解析到此結束。

  2. 操作系統緩存

    如果上一步沒有找到對應的條目,瀏覽器會搜索操作系統自身的 DNS 緩存,如果找到了沒有過期的對應條目,則停止搜索,解析到此結束。查看操作系統自身的 DNS 緩存,以 Windows 系統為例,win + R 後輸入 cmd 命令提示行,輸入ipconfig /displaydns 進行查看。

  3. hosts 文件

    如果上一步沒有找到對應條目,瀏覽器就會嘗試讀取操作系統本地的文件,以 Windows 系統為例:C:\Windows\System32\drivers\etc內的 hosts 文件。

  4. DNS 伺服器

    如果以上的三步都沒有找到對應條目,那麼瀏覽器就會向 DNS 伺服器請求進行功能變數名稱解析。

    更具體地說,瀏覽器發起一個 DNS 的系統調用,向本地配置的首選 DNS 伺服器(一般由運營商提供)發起功能變數名稱解析請求。功能變數名稱解析請求是通過 UDP 協議向DNS 的 53 埠發起請求,這個請求是遞歸的請求。也就是說,運營商的 DNS 伺服器必須得提供給我們該功能變數名稱的公網 IP 地址。

2.2TCP 連接

根據 DNS 伺服器解析出的 IP 地址和預設埠號,與該伺服器進行 TCP 連接中 3 次握手的前兩次,來建立連接:

TCP 連接

2.3發送 HTTP 請求

即完成 TCP 的 3 次握手的第三次:

發送 HTTP 請求

2.4伺服器應答

客戶端發起了請求,伺服器一定要有應答嗎?要回答這個問題,得知道 HTTP 響應的底層原理是基於 HTTP 協議的通信機制,這個協議決定了:如果客戶端發送的請求能準確到達伺服器,那麼伺服器必須會有響應並返回。

在本文的第四章,我會拿一個部署在 Linux 伺服器上的、基於Spring Boot 的 Java 程式來分析具體伺服器是怎麼做出響應的。

伺服器應答

2.5響應內容

下麵是訪問 https://mvnrepository.com/ 即 Maven 遠程中央倉庫時,調用其搜索介面所產生的響應標頭內容:

響應內容

2.6關閉連接

最後瀏覽器會關閉該 TCP 連接,瀏覽器利用自己內部的工作機制,把請求到的靜態資源和 HTML 代碼進行渲染,呈現給用戶。


三、客戶端請求

下麵其實是本文的重頭戲,會重點講解具體的 HTTP 請求是怎麼構建、發送請求的。

3.1請求Header

一個 HTTP 請求報文由請求行(request line)、請求頭部(headers)、請求數據(request body)和空行(blank line)4個部分組成。

其中請求頭部(headers)為請求報文添加了一些附加信息,由鍵值對組成,每行一對,名和值之間使用冒號分隔,如下圖是由 PostMan 調用所示:

響應內容
請求 Header

常見的幾個請求頭釋義:

常見請求頭

且我們還可以自定義 Header 如:Authorization 是認證信息、Tenant-Code 是發起本次請求的租戶編碼。

註意:由於 HTTP 協議只規定 POST 提交的數據必須放在消息主體(body)中,並沒有規定數據必須使用什麼編碼方式。服務端通常是根據請求頭中的 Content-Type 欄位來獲知請求中的消息主體是用何種方式編碼,再對 body 進行解析。

常用的 Content-Type 編碼方式有:

  • application/x-www-form-urlencoded 數據在發送到伺服器之前,會將表單內的數據轉換為鍵值對,比如 username=admin&password=123456,並將所有字元都會進行 URL 轉碼;
  • multipart/form-data 數據將被編碼為一條消息以標簽為單元,用分隔符分開,既可以上傳鍵值對,也可以上傳文件,通常用於上傳二進位的文件;
  • application/json 用來告訴服務端消息主體是序列化後的 JSON 字元串,前端無法將表單的 enctype 屬性指定為 application/json,通常使用 Ajax 的方式發送這種編碼形式的請求。

3.2請求方法

最常用的四種請求方法:GET、POST、PUT、DELETE。

常見 HTTP 請求方法

3.3cookie 和 token

在瞭解 Session 和 Cookies 之前,我們還需要瞭解 HTTP 的一個特點,叫作無狀態。

HTTP 的無狀態是指 HTTP 協議對事務處理是沒有記憶能力的,也就是說伺服器不知道客戶端是什麼狀態。

這時兩個用於保持 HTTP 連接狀態的技術就出現了,它們分別是 Session 和 Cookie。

Session 在服務端,也就是網站的伺服器,用來保存用戶的 Session 信息。

Cookie 在客戶端,也可以理解為瀏覽器端有了 Cookie,瀏覽器在下次訪問網頁時會自動附帶上它發送給伺服器,伺服器通過識別 Cookie 並鑒定出是哪個用戶,然後再判斷用戶是否是登錄狀態,進而返回對應的響應。


四、服務端響應

4.1demo 舉例

這裡以一個基於 Spring Boot 的 Java 程式來舉例,@RequestMapping 是 Spring MVC 框架中的一個註解,它用於指示具體的 Controller 方法如何響應某個特定的請求。它可以用於將請求URL映射到控制器上,並可以指定不同的參數設置。

@RestController
@RequestMapping("/study")
public class StudyController {

    @Resource
    private StudyService studyService;

    /**
     * 新增
     * @param studyDTO
     * @return 是否成功
     */
    @PostMapping("/add")
    public BaseResponse<Boolean> addAwards(@RequestBody StudyDTO studyDTO) {
        return ResultUtils.success(studyService.addStudy(studyDTO));
    }
}

如果將這個應用部署在伺服器上,你想訪問到,那麼需要在瀏覽器中輸入:https://ip+port/服務名/study/add

我自己本地訪問則是:http://localhost:28089/initial/study/add

4.2返回內容

那麼 HTTP 返回的響應報文內容是什麼?主要包括以下3個部分:

  • 響應狀態行(Status Line):包含HTTP協議版本、響應狀態碼和狀態消息。例如,HTTP/1.1 200 OK 表示 HTTP 協議版本是1.1,響應狀態碼是 200,狀態消息是 OK。這個在下一節會單獨拿出來講。

  • 響應頭部(Headers):包含了一系列的鍵值對,用來描述響應的屬性和元數據。常見的響應頭包括 Content-Type(指定響應的數據類型)、Content-Length(指定響應體的長度)等。HTTP 協議定義了許多標準的響應頭,不同的頭部欄位有不同的作用。

    以下是一些常見的響應頭:

    • Content-Type:指定響應體的數據類型。例如,Content-Type: text/html 表示響應體是 HTML 文檔。

    • Content-Length:指定響應體的長度,以位元組為單位。例如,Content-Length: 1024 表示響應體的長度是 1024 位元組。

    • Location:用於重定向客戶端到新的URL。例如,Location: http://example.com/new_page 會將客戶端重定向到 http://example.com/new_page。

    • Set-Cookie:用於設置 Cookie,可以在響應中向客戶端發送 Cookie 信息。

    • Cache-Control:控制響應的緩存行為,包括緩存的過期時間、驗證方式等。

    • Server:指定響應的伺服器信息。例如,Server: Apache/2.4.38 表示響應是由 Apache 伺服器版本 2.4.38 生成的。

  • 響應體(Body):包含了實際的響應數據,可以是HTML頁面、JSON數據、文本等。響應體的格式由Content-Type頭部欄位指定。

    以下是一些常見的Content-Type值:

    • text/html:HTML 文檔。

    • application/json:JSON 數據。

    • text/plain:純文本。

    • image/jpeg:JPEG圖像。

    • application/xml:XML 數據。

4.3返回狀態碼

以下是一些常見的HTTP響應狀態碼:

常見 HTTP 響應狀態碼

五、文章小結

無論是前端還是後端,不論是科班還是非科班,也無論是開發、測試還是產品,瞭解和掌握 HTTP 請求的一些基本知識都是非常重要的。它是現代互聯網中不可或缺的一部分,為我們提供了高效、靈活、可靠的數據傳輸方式,為 Web 應用程式的開發和使用提供了強有力的支持。

今天的分享就到這裡,如有不足和錯誤,還請大家指正。或者你有其它想說的,也歡迎大家在評論區交流!

參考文檔:

https://blog.csdn.net/u010804417/article/details/123638124

https://www.cnblogs.com/engeng/articles/5959335.html


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 引言 在現代的互聯網應用中,數據安全和隱私保護變得越來越重要。尤其是在介面返回數據時,如何有效地對敏感數據進行脫敏處理,是每個開發者都需要關註的問題。本文將通過一個簡單的Spring Boot項目,介紹如何實現介面數據脫敏。 一、介面數據脫敏概述 1.1 介面數據脫敏的定義 介面數據脫敏是指在介面返 ...
  • 本文介紹基於R語言中的UBL包,讀取.csv格式的Excel表格文件,實現SMOTE演算法與SMOGN演算法,對機器學習、深度學習回歸中,訓練數據集不平衡的情況加以解決的具體方法~ ...
  • 什麼是I8n 國際化(I18n)指的是設計和開發產品的過程,使得它們能夠適應多種語言和文化環境,而不需要進行大量的代碼更改。這通常涉及到創建一個基礎版本的產品,然後通過配置和資源文件來添加對不同語言和地區的支持。 這樣,當產品需要在新的地理區域或語言環境中使用時,只需要添加或更新相應的資源文件,而不 ...
  • 目錄<future>future模板類成員函數:promise類promise的使用常式:packaged_task模板類常式:async模板函數常式:shared_future模板類 <future> 標準庫提供了一些工具來獲取非同步任務(即在單獨的線程中啟動的函數)的返回值,並捕捉其所拋出的異常。 ...
  • 目錄<condition_variable>condition_variable類類方法生產者消費者模型 -- 阻塞隊列單條件變數版condition_variable_any模板類區別優缺點 <condition_variable> 條件變數是C++11提供的另外一種用於等待的同步機制,它能阻塞一 ...
  • 大家好,我是 Java陳序員。 我們在日常生活中,有時候因為工作需要,需要發佈一些問卷調查,來統計數據,獲得反饋! 今天,給大家介紹一款開箱即用的開源問卷調查系統! 關註微信公眾號:【Java陳序員】,獲取開源項目分享、AI副業分享、超200本經典電腦電子書籍等。 項目介紹 TDuck —— 一款 ...
  • 工作中只要接觸過第三方開放平臺的都離不開 OpenApi,幾乎各大平臺都會有自己的 OpenApi 比如微信、淘寶、京東、抖音等。在 OpenApi 對接的過程中最首要的環節就是授權,獲取到平臺的授權 Token 至關重要。 ...
  • 目錄<mutex>std::call_once函數常式:使用call_once實現的單例模式std::mutex類 -- 獨占互斥鎖成員函數std::recursive_mutex類 -- 遞歸互斥鎖使用註意:描述:std::timed_mutex類 -- 超時互斥鎖描述:成員函數:std::rec ...
一周排行
    -Advertisement-
    Play Games
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...