博客 / 詳情

返回

普通Fetch和Fetch 流式的區別?

🧑‍💻 寫在開頭

點贊 + 收藏 === 學會🤣🤣🤣

你想弄清楚 Fetch 流式的核心定義、工作原理和實際價值,簡單來説,Fetch 流式是 Fetch API 提供的「邊接收、邊處理」數據的能力,它讓前端不再需要等待服務端返回完整的響應數據,而是能逐塊讀取、處理數據,是前端處理大文件、實時數據的核心能力之一。


一、Fetch 流式的核心定義

Fetch 流式(Fetch Streaming)是基於瀏覽器原生 Fetch API 實現的流式數據處理能力

  • 普通 Fetch 請求:服務端返回完整的響應數據,前端一次性接收所有數據後才能處理(比如 res.json()/res.text() 都是一次性解析);
  • Fetch 流式:服務端通過 HTTP Chunked(分塊傳輸編碼)返回數據,Fetch 請求的響應體 response.body 會返回 ReadableStream(可讀流)對象,前端可以逐塊讀取服務端發送的「數據塊」,邊接收、邊解析、邊處理,無需等待整個響應完成。

核心原理(一句話講透)

Fetch 流式的底層是「HTTP 分塊傳輸 + 瀏覽器 Streams API」的組合:

  1. 服務端開啓 HTTP Chunked 編碼,將數據切分成多個獨立的「數據塊」,逐個發送給前端;
  2. 前端 Fetch 拿到響應後,response.body 暴露為 ReadableStream 可讀流;
  3. 前端通過流的讀取器(reader)逐塊讀取這些數據,實現流式處理。

二、Fetch 流式的核心用法(極簡代碼示例)

Fetch 流式的核心是操作 response.body(ReadableStream),以下是最常見的 2 個場景:

場景 1:流式讀取文本 / JSON 數據(比如實時日誌、大模型打字機效果)

async function streamFetchText(url) {
  // 1. 發起 Fetch 請求
  const response = await fetch(url);
  
  // 校驗:確保響應有效且支持流式(response.body 是 ReadableStream)
  if (!response.ok || !response.body) {
    throw new Error("請求失敗或不支持流式響應");
  }

  // 2. 獲取流的讀取器
  const reader = response.body.getReader();
  // 3. 二進制流轉文本的解碼器(關鍵:stream: true 保證分塊解碼不亂碼)
  const decoder = new TextDecoder("utf-8", { stream: true });

  try {
    // 4. 循環逐塊讀取數據(流式核心邏輯)
    while (true) {
      // done: 是否讀取完成;value: 當前數據塊(Uint8Array 二進制格式)
      const { done, value } = await reader.read();
      
      if (done) break; // 讀取完成,退出循環

      // 5. 實時處理當前數據塊(比如渲染到頁面、解析JSON)
      const chunkText = decoder.decode(value);
      console.log("實時讀取的內容塊:", chunkText);
      // 示例:實時追加到頁面(模擬大模型打字機效果)
      document.getElementById("content").textContent += chunkText;
    }
  } finally {
    // 6. 釋放讀取器(關鍵:避免內存泄漏)
    reader.releaseLock();
  }
}

// 調用示例(比如請求返回流式文本的接口)
streamFetchText("/api/stream-log");

場景 2:流式下載大文件(避免內存溢出)

async function streamDownloadFile(url, fileName) {
  const response = await fetch(url);
  if (!response.ok || !response.body) throw new Error("下載失敗");

  // 1. 將流式響應體轉為 Blob(瀏覽器自動拼接分塊數據)
  const blob = await new Response(response.body).blob();
  // 2. 創建下載鏈接並觸發下載
  const downloadUrl = URL.createObjectURL(blob);
  const a = document.createElement("a");
  a.href = downloadUrl;
  a.download = fileName;
  a.click();

  // 3. 清理資源
  URL.revokeObjectURL(downloadUrl);
}

// 調用示例(下載1GB+的大文件)
streamDownloadFile("/api/download/large-file", "超大文件.zip");

三、Fetch 流式的核心使用場景

  1. 大文件下載:下載 100MB+ 的文件時,流式下載僅佔用少量內存,避免一次性加載導致的頁面卡頓 / 內存溢出;
  2. 實時數據接收:接收服務端推送的實時日誌、後台任務進度、大模型的流式響應(打字機效果);
  3. 超大 JSON 解析:服務端返回百萬條數據的 JSON 列表時,流式逐塊解析,實時渲染到頁面(比如表格);
  4. 二進制流處理:流式讀取圖片 / 視頻等二進制文件,實時預覽或處理(比如圖片壓縮)。

四、Fetch 流式 vs 普通 Fetch 的核心區別

ScreenShot_2026-02-12_203637_684

總結

  1. 核心本質:Fetch 流式是 Fetch API 結合 HTTP Chunked 分塊傳輸,通過 response.body(ReadableStream)實現的逐塊數據處理能力;
  2. 核心價值:解決大文件 / 實時數據一次性加載導致的「內存溢出、頁面卡頓、等待時間長」問題;
  3. 核心用法:通過 reader.read() 循環讀取數據塊,配合 TextDecoder 處理文本,或直接轉為 Blob 實現流式下載。

如果對您有所幫助,歡迎您點個關注,我會定時更新技術文檔,大家一起討論學習,一起進步。

user avatar
0 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.