小白也能看懂,HTTP中的文件上傳與下載到底發生了什么?

HTTP 文件傳輸協議解析:上傳與下載

這份文檔會用最簡單的方式,帶你了解 HTTP 協議是如何處理文件下載和上傳的。我們會專注于協議本身,看看客戶端(比如你的瀏覽器)和服務端(網站服務器)之間到底在“聊”些什么。

1. 文件下載:從服務器“拉”數據

文件下載相對簡單,核心就是一個 GET 請求。你可以把它想象成你對服務器說:“嘿,請把那個文件給我”。

過程解析

  1. 客戶端發起請求: 你的瀏覽器向服務器發送一個 GET 請求,請求的 URL 就是那個文件的地址。

  2. 服務器響應: 服務器收到請求后,如果文件存在且你有權限訪問,它就會返回一個 HTTP 響應。這個響應的“身體”(Response Body)里就裝著文件的完整二進制數據。

關鍵的 HTTP 報文(Headers)

在下載過程中,服務器的響應報文(Response Headers)非常重要,它們會告訴瀏覽器如何處理接收到的數據。

  • Content-Type: 這個字段告訴瀏覽器這是個什么類型的文件。

    • image/jpeg: 一個 JPEG 圖片

    • application/pdf: 一個 PDF 文件

    • text/plain: 純文本

    • text/markdown; charset=utf-8: 一個 Markdown 文本文件,使用 UTF-8 編碼。

    • application/octet-stream: 這是個通用的二進制文件類型,瀏覽器通常不知道如何直接打開它,于是會提示用戶下載。

  • Content-Length: 這個字段告訴瀏覽器文件有多大(單位是字節)。這樣瀏覽器就可以顯示下載進度條了。

  • Content-Disposition: 這是個非常有用的字段。

    • 如果它的值是 inline,瀏覽器會嘗試直接在頁面里顯示這個文件(比如圖片、PDF)。

    • 如果它的值是 attachment; filename="your-file-name.zip",瀏覽器會立即彈出下載對話框,并使用 filename 指定的文件名作為默認保存名。

  • Last-Modified: 文件在服務器上最后一次被修改的時間。這個信息可以被瀏覽器用來做緩存判斷,避免重復下載沒有變化的文件。

  • ETag (Entity Tag): 文件的“指紋”或版本號。這是一個唯一的字符串,只要文件內容有變動,ETag 就會改變。它也是用來做緩存控制的,比 Last-Modified 更精確。

  • Accept-Ranges: 告訴客戶端,服務器是否支持“范圍請求”(即只請求文件的一部分)。值為 bytes 表示支持,這對于實現斷點續傳功能至關重要。

  • Server: 響應這個請求的服務器軟件名稱和版本,例如 Apache, Nginx, uvicorn

  • Date: 服務器生成并發送此響應的時間。

下載示例(協議層面)

示例一:簡單示例
# 1. 客戶端(瀏覽器)的請求
GET /files/document.pdf HTTP/1.1
Host: example.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) ...# 2. 服務器的響應
HTTP/1.1 200 OK
Content-Type: application/pdf
Content-Length: 102400
Content-Disposition: attachment; filename="report.pdf"# (這里是 102400 字節的 PDF 文件二進制數據)
...
示例二:包含更多信息的詳細示例
HTTP/1.1 200 OK
Date: Thu, 04 Sep 2025 08:16:55 GMT
Server: uvicorn
Content-Type: text/markdown; charset=utf-8
Content-Length: 12004
Content-Disposition: attachment; filename="parsed_6983e807-f1f9-4416-77d52c295a80.md"
Last-Modified: Thu, 04 Sep 2025 07:44:51 GMT
ETag: "13b5d596f8229a520b7ccd9f889b290c"
Accept-Ranges: bytes# (這里是 12004 字節的 Markdown 文件數據)
...

2. 文件上傳:向服務器“推”數據

文件上傳比下載要復雜一些,核心是使用 POSTPUT 請求。你可以把它想象成你要給服務器寄一個包裹。

文件是如何被發送的?(一個比喻)

上傳時,發送的并不是文件的路徑,而是文件內容的完整二進制數據。瀏覽器會打開這個文件,讀取里面所有的數據,然后把這些原始的二進制數據流直接放進 HTTP 請求的 Body(請求體)里。

和普通 POST 表單提交有何不同?

文件上傳和普通的 POST 表單提交不一樣,關鍵區別在于 Content-Type 和請求體的數據結構

  • 普通 POST 表單提交: Content-Type 通常是 application/x-www-form-urlencoded,請求體是 key=value&key2=value2 這樣的字符串,只適合文本。

  • 文件上傳 POST: Content-Type 必須是 multipart/form-data,請求體被分割成多個部分,可以同時容納文本和二進制文件。

問題一:文件是如何被打包成一個整體的?

你的理解有一點點偏差,這是一個非常常見的誤區。

  • 誤區:把一個大文件的二進制數據,用分割符切成若干個小參數來發送。

  • 正確理解:分割符(boundary)的作用是分隔不同的表單項,而不是用來切割單個文件。

你可以把整個請求體(Request Body)想象成一個大包裹。

  1. 包裹里有不同的“隔間”,boundary 就是這些隔間的“分隔板”。

  2. 一個隔間放你的用戶名(一個 part)。

  3. 另一個隔間放你上傳的文件(另一個 part)。

  4. 整個文件的完整二進制數據,是作為一個整體,被原封不動地放進它自己所屬的那個“隔間”里的。它并沒有被boundary切割。

所以,請求體看起來像這樣:
[分隔板] -> [用戶名字段] -> [分隔板] -> [一整個文件的完整二進制數據] -> [帶結尾的分隔板]

問題二:這塊打包好的數據如何傳輸?會很大嗎?

這里依次回答你的問題:

  1. 這塊數據怎么傳輸呢?是和普通的post請求一樣通過一個鍵值對的值發送嗎?

    • 不,它不是通過一個鍵值對的值發送的。這一點是 multipart/form-dataapplication/x-www-form-urlencoded 的根本區別。這一整塊被 boundary 分隔的數據,它本身就是 HTTP 請求的 Body(請求體)的全部內容。HTTP 請求頭中的 Content-Type: multipart/form-data; ... 就像是這個 Body 的“說明書”,告訴服務器:“接下來我發送的 Body 是一個多部分格式的數據,請你用這個 boundary 字符串來解析它”,而不是一個簡單的 key=value 字符串。
  2. 這一塊數據會不會特別大?

    • 會的。請求體的大小約等于所有文件的大小 + 所有文本字段的大小 + 分隔符和頭部信息的額外開銷。如果你上傳一個 100MB 的視頻,那么這個 HTTP POST 請求的 Body 大小就會超過 100MB。這也就是為什么服務器通常會設置一個“請求體大小限制”(比如 200MB),以防止惡意用戶或程序通過上傳超大文件耗盡服務器資源。
  3. 抓包的話是不是會看到這個一整塊的二進制數據?

    • 完全正確。如果你使用像 Wireshark 這樣的網絡抓包工具,并捕獲了這次上傳的流量,你將能夠清晰地看到整個 HTTP POST 請求的原始報文。你會先看到請求頭(Request Headers),緊接著就是原封不動的請求體(Request Body),其中包含了所有的 boundary 分隔符、每個部分的 Content-Disposition,以及那個文件的、未經加密的、完整的二進制數據流。

問題三:服務器如何接收并還原文件?

服務器收到數據后,會進行一系列“拆包”和“還原”操作。

  • a. 識別包裹類型: 服務器首先檢查請求頭的 Content-Type,看到是 multipart/form-data,并且獲取到了那個獨一無二的 boundary 字符串。

  • b. 按分隔板拆包: 服務器的應用程序(比如 PHP, Python, Java 的 Web 框架)會使用這個 boundary 字符串作為標記,去掃描整個請求體。每當遇到一個 boundary,它就知道這是一個新部分的開始。

  • c. 解析每個部分:

    • 對于文本部分,服務器直接讀取 name 和它的值(比如 usernameJohn)。

    • 對于文件部分,服務器會讀取它的 name(比如 userfile)和 filename(比如 avatar.png),然后將這個部分包含的、連續的、完整的二進制數據流讀取出來

  • d. 還原文件: 服務器通常會把這個讀取出來的二進制數據流暫存到服務器磁盤上的一個臨時文件中,或者直接在內存中處理。至此,你在本地電腦上的那個文件,就以一個臨時文件的形式,在服務器上被完整地“復制”或“還原”了出來。后續程序就可以對這個還原后的文件進行永久保存、病毒掃描或其他處理了。

一個簡單的上傳示例(協議層面)

假設我們要上傳一個名為 avatar.png 的圖片,并且附帶一個用戶名字段 username,值為 John

# 客戶端(瀏覽器)的請求
POST /upload HTTP/1.1
Host: example.com
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Length: 437# (下面是請求體 Request Body 的內容)
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="username"John
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="userfile"; filename="avatar.png"
Content-Type: image/png# (這里是 avatar.png 文件的完整二進制數據,沒有被切割)
...
------WebKitFormBoundary7MA4YWxkTrZu0gW--

總結

操作HTTP 方法數據位置關鍵 Content-Type
下載GET響應體 (Response Body)application/octet-stream, image/jpeg
上傳POST / PUT請求體 (Request Body)multipart/form-data

簡單來說:

  • 下載 就是客戶端發一個簡單的 GET 請求,服務器把文件放在響應體里發回來。

  • 上傳 就是客戶端發一個結構化的 POST 請求,用 multipart/form-data 格式把文件和其他信息打包放在請求體里發過去。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/921675.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/921675.shtml
英文地址,請注明出處:http://en.pswp.cn/news/921675.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

快速構建數據集-假數據(生成劃分)

快速構建數據集-假數據1、torch.randn(?)2、HuggingFace Datasets(?)🔹1. 從字典生成🔹2. 從 pandas.DataFrame 生成🔹3. 批量生成“業務型”假數據(配合 Faker)&#…

[修訂版]Xenomai/IPIPE源代碼情景解析

[修訂版]Xenomai/IPIPE源代碼情景解析 第一章:Interrupt Pipeline介紹 1.1 I-pipe與Xenomai1.2 I-pipe核心概念1.3 拉取I-pipe代碼 第二章:I-pipe對ARM64異常的改造 2.1 ARM64中斷機制與異常處理2.2 EL0_IRQ 中斷改造之入口2.3 EL0_IRQ 中斷改造之中斷處…

【Qt開發】按鈕類控件(三)-> QCheckBox

目錄 1 -> 概述 2 -> 核心特性 2.1 -> 狀態管理 2.2 -> 信號機制 2.3 -> 外觀與文本 3 -> 應用場景 4 -> 代碼示例 5 -> 總結 1 -> 概述 QCheckBox 是 Qt 框架中提供的一個基礎控件,用于實現復選框功能。它允許用戶在兩種或三種…

在新發布的AI論文中 pytorch 和tensorflow 的使用比例

根據 2025 年最新的學術動態和行業報告,PyTorch 在 AI 論文中的使用比例已占據絕對主導地位,而 TensorFlow 的占比持續下降。以下是基于多個權威來源的綜合分析: 一、頂級會議中的框架分布 在 NeurIPS、ICML、CVPR 等頂級學術會議中&#xff…

3DXML格式是什么?用什么軟件可以打開?

3DXML 是一種開放標準的數據交換格式,主要用于三維 CAD(計算機輔助設計)模型的存儲和交換。它是由 Dassault Systmes 開發的一種文件格式,常用于 CATIA V6 和其他支持該格式的應用程序中。3DXML 文件可以包含完整的 3D 模型數據&a…

9月8日星期一今日早報簡報微語報早讀

9月8日星期一,農歷七月十七,早報#微語早讀。1、中國火箭與月亮同框,遙感四十號03組衛星發射成功;2、湖南郴州開發區改革:編制數由815名減至680名,精簡16.6%;3、水利部對廣東、廣西啟動洪水防御Ⅳ…

windows系統搭建MQTT服務器

1、MQTT 協議 MQTT協議:實現MQTT協議需要客戶端和服務器端通訊完成。 三種身份: 發布者(Publish)、代理(Broker)(服務器)、訂閱者(Subscribe)。 消息的發布者和訂閱者都是客戶端,消息代理是服務器,消息發布者可以同時是訂閱者。 MQTT&am…

從 GPT 到 LLaMA:解密 LLM 的核心架構——Decoder-Only 模型

🔥從 GPT 到 LLaMA:解密 LLM 的核心架構——Decoder-Only 模型 “為什么所有大模型(LLM)都長一個樣?” 因為它們都有一個共同的“基因”——Decoder-Only 架構。 在前面兩節中,我們學習了: BER…

Codeforces Round 1047 (Div. 3)

由于最近這三天的數學建模,讓我這個精力本來就不多的AI手更加力竭了,沒注意到昨晚的cf,所以今天來補題了。 比賽連接:比賽傳送門 A題: You are doing a research paper on the famous Collatz Conjecture. In your e…

C++經典的數據結構與算法之經典算法思想:貪心算法(Greedy)

貪心算法(Greedy Algorithm):通過局部最優達成全局最優的決策策略 貪心算法是一種通過每次選擇局部最優解來期望全局最優解的算法思想。它不考慮未來的影響,僅根據當前信息做出最優選擇,適用于具有貪心選擇性質和最優子…

LangChain實戰(二十一):構建自動化AI客服系統

本文是《LangChain實戰課》系列的第二十一篇,將帶領您構建一個完整的自動化AI客服系統。通過結合對話記憶、工具調用和業務知識庫,我們將創建一個能夠處理復雜客戶查詢的智能客服解決方案。 前言 在現代商業環境中,客戶服務是企業成功的關鍵因素之一。傳統客服系統往往面臨…

一人公司智能管理系統概述

系統概述 項目結構 Al_Compny系統采用前后端分離的全棧架構,項目根目錄下包含兩個主要子目錄:Al_Compny_backend(后端服務)和Al_Compny_frontend(前端應用)。核心功能模塊 Al_Compny系統是一個面向"一…

OpenWrt | 在 PPP 撥號模式下啟用 IPv6 功能

文章目錄一、WAN 口配置二、LAN 口配置三、IPv6 測試本文將詳細介紹 將光貓的網絡模式改成橋接之后使用路由器撥號的上網方式的情況下,在 OpenWrt 上使用 PPP 撥號模式上網時,啟用 IPv6 功能的方法。 一、WAN 口配置 首先,我們需要在 網絡 …

Java如何實現一個安全的登錄功能?

安全登錄系統完整教程 📋 目錄 項目概述技術棧安全特性項目結構核心組件詳解安全實現原理部署和運行安全最佳實踐常見問題解答進階擴展 🎯 項目概述 這是一個基于Spring Boot和Spring Security的完整安全登錄系統,專為初學者設計&#xff…

星辰誕愿——生日快樂

前言 今天這篇博客并非技術文章,而是慶祝我可愛的妹妹18歲生日以及介紹我半年以來的學習經歷 祝生網站:星辰誕愿(用戶列表里第一位就是我妹妹,希望大家能獻上自己的祝福,能分享轉發更好,我在此感謝大家。如果使用手機&…

基于STM32單片機的智能糧倉溫濕度檢測藍牙手機APP設計

基于STM32單片機的智能糧倉溫濕度檢測藍牙手機APP設計 1 系統功能介紹 本系統是一款基于STM32單片機的智能糧倉環境監測與控制裝置,核心目標是通過傳感器實時采集糧倉內的溫度和濕度信息,并結合藍牙通信模塊將數據傳輸至手機端,實現對糧倉環境…

簡單視頻轉換器 avi轉mp4

直接上代碼package com.example.videoconverter;import ws.schild.jave.Encoder; import ws.schild.jave.EncoderException; import ws.schild.jave.MultimediaObject; import ws.schild.jave.encode.AudioAttributes; import ws.schild.jave.encode.EncodingAttributes; impor…

Kafka 與 RocketMQ 核心概念與架構對比

Kafka 與 RocketMQ 核心概念與架構對比DeepSeek生成,便于記憶大概邏輯核心概念對比圖 #mermaid-svg-dEbo1XpAjfzOjvUW {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-dEbo1XpAjfzOjvUW .error-icon{fill…

30分鐘深度壓測cuBLAS:從FP64到INT8全精度性能剖析

在深度學習和高性能計算領域,GPU的矩陣運算性能是衡量系統算力的核心指標之一。NVIDIA的cuBLAS庫作為CUDA平臺上最基礎的線性代數計算庫,其性能表現直接影響著上層應用的運行效率。本文將詳細介紹如何使用cublasmatmulbench工具對多GPU進行全面的性能基準…

超越模仿:探尋智能的本源

引言:超越模仿,探尋智能的本源近年來,以大語言模型(LLM)為代表的自然語言處理(NLP)技術,在模仿人類語言生成方面取得了令人矚目的成就。從流暢的對話到精煉的文本摘要,機…