普通Fetch和Fetch流式的區(qū)別詳解(極簡代碼示例)
前言
你想弄清楚 Fetch 流式的核心定義、工作原理和實(shí)際價(jià)值,簡單來說,Fetch 流式是 Fetch API 提供的「邊接收、邊處理」數(shù)據(jù)的能力,它讓前端不再需要等待服務(wù)端返回完整的響應(yīng)數(shù)據(jù),而是能逐塊讀取、處理數(shù)據(jù),是前端處理大文件、實(shí)時(shí)數(shù)據(jù)的核心能力之一。
一、Fetch 流式的核心定義
Fetch 流式(Fetch Streaming)是基于瀏覽器原生 Fetch API 實(shí)現(xiàn)的流式數(shù)據(jù)處理能力:
- 普通 Fetch 請求:服務(wù)端返回完整的響應(yīng)數(shù)據(jù),前端一次性接收所有數(shù)據(jù)后才能處理(比如
res.json()/res.text()都是一次性解析); - Fetch 流式:服務(wù)端通過 HTTP Chunked(分塊傳輸編碼)返回?cái)?shù)據(jù),F(xiàn)etch 請求的響應(yīng)體
response.body會返回ReadableStream(可讀流)對象,前端可以逐塊讀取服務(wù)端發(fā)送的「數(shù)據(jù)塊」,邊接收、邊解析、邊處理,無需等待整個(gè)響應(yīng)完成。
核心原理(一句話講透)
Fetch 流式的底層是「HTTP 分塊傳輸 + 瀏覽器 Streams API」的組合:
- 服務(wù)端開啟 HTTP Chunked 編碼,將數(shù)據(jù)切分成多個(gè)獨(dú)立的「數(shù)據(jù)塊」,逐個(gè)發(fā)送給前端;
- 前端 Fetch 拿到響應(yīng)后,
response.body暴露為ReadableStream可讀流; - 前端通過流的讀取器(
reader)逐塊讀取這些數(shù)據(jù),實(shí)現(xiàn)流式處理。
二、Fetch 流式的核心用法(極簡代碼示例)
Fetch 流式的核心是操作 response.body(ReadableStream),以下是最常見的 2 個(gè)場景:
場景 1:流式讀取文本 / JSON 數(shù)據(jù)(比如實(shí)時(shí)日志、大模型打字機(jī)效果)
async function streamFetchText(url) {
// 1. 發(fā)起 Fetch 請求
const response = await fetch(url);
// 校驗(yàn):確保響應(yīng)有效且支持流式(response.body 是 ReadableStream)
if (!response.ok || !response.body) {
throw new Error("請求失敗或不支持流式響應(yīng)");
}
// 2. 獲取流的讀取器
const reader = response.body.getReader();
// 3. 二進(jìn)制流轉(zhuǎn)文本的解碼器(關(guān)鍵:stream: true 保證分塊解碼不亂碼)
const decoder = new TextDecoder("utf-8", { stream: true });
try {
// 4. 循環(huán)逐塊讀取數(shù)據(jù)(流式核心邏輯)
while (true) {
// done: 是否讀取完成;value: 當(dāng)前數(shù)據(jù)塊(Uint8Array 二進(jìn)制格式)
const { done, value } = await reader.read();
if (done) break; // 讀取完成,退出循環(huán)
// 5. 實(shí)時(shí)處理當(dāng)前數(shù)據(jù)塊(比如渲染到頁面、解析JSON)
const chunkText = decoder.decode(value);
console.log("實(shí)時(shí)讀取的內(nèi)容塊:", chunkText);
// 示例:實(shí)時(shí)追加到頁面(模擬大模型打字機(jī)效果)
document.getElementById("content").textContent += chunkText;
}
} finally {
// 6. 釋放讀取器(關(guān)鍵:避免內(nèi)存泄漏)
reader.releaseLock();
}
}
// 調(diào)用示例(比如請求返回流式文本的接口)
streamFetchText("/api/stream-log");場景 2:流式下載大文件(避免內(nèi)存溢出)
async function streamDownloadFile(url, fileName) {
const response = await fetch(url);
if (!response.ok || !response.body) throw new Error("下載失敗");
// 1. 將流式響應(yīng)體轉(zhuǎn)為 Blob(瀏覽器自動(dòng)拼接分塊數(shù)據(jù))
const blob = await new Response(response.body).blob();
// 2. 創(chuàng)建下載鏈接并觸發(fā)下載
const downloadUrl = URL.createObjectURL(blob);
const a = document.createElement("a");
a.href = downloadUrl;
a.download = fileName;
a.click();
// 3. 清理資源
URL.revokeObjectURL(downloadUrl);
}
// 調(diào)用示例(下載1GB+的大文件)
streamDownloadFile("/api/download/large-file", "超大文件.zip");三、Fetch 流式的核心使用場景
- 大文件下載:下載 100MB+ 的文件時(shí),流式下載僅占用少量內(nèi)存,避免一次性加載導(dǎo)致的頁面卡頓 / 內(nèi)存溢出;
- 實(shí)時(shí)數(shù)據(jù)接收:接收服務(wù)端推送的實(shí)時(shí)日志、后臺任務(wù)進(jìn)度、大模型的流式響應(yīng)(打字機(jī)效果);
- 超大 JSON 解析:服務(wù)端返回百萬條數(shù)據(jù)的 JSON 列表時(shí),流式逐塊解析,實(shí)時(shí)渲染到頁面(比如表格);
- 二進(jìn)制流處理:流式讀取圖片 / 視頻等二進(jìn)制文件,實(shí)時(shí)預(yù)覽或處理(比如圖片壓縮)。
四、Fetch 流式 vs 普通 Fetch 的核心區(qū)別
| 維度 | 普通 Fetch | Fetch 流式 |
|---|---|---|
| 數(shù)據(jù)接收方式 | 一次性接收完整響應(yīng)數(shù)據(jù) | 逐塊接收服務(wù)端的分塊數(shù)據(jù) |
| 響應(yīng)體類型 | 需通過 res.json()/res.text()一次性解析 | response.body是 ReadableStream 可讀流 |
| 內(nèi)存占用 | 完整數(shù)據(jù)存入內(nèi)存,大文件易溢出 | 僅占用當(dāng)前數(shù)據(jù)塊的內(nèi)存,占用恒定 |
| 處理時(shí)機(jī) | 必須等待響應(yīng)完全返回后才能處理 | 邊接收、邊處理,實(shí)時(shí)響應(yīng) |
| 適用場景 | 小數(shù)據(jù) / 小文件請求 | 大文件、實(shí)時(shí)數(shù)據(jù)、超大 JSON 請求 |
注意事項(xiàng)
服務(wù)器必須支持流式響應(yīng):需要設(shè)置
Transfer-Encoding: chunked或使用支持流式輸出的框架(如 Node.js 的res.write()、Spring WebFlux、FastAPI 的StreamingResponse)。瀏覽器兼容性:現(xiàn)代瀏覽器均支持
response.body,但 IE 不支持。JSON 流式解析:如果服務(wù)器返回的是多個(gè) JSON 對象(如每行一個(gè)),不能直接用
response.json(),需要手動(dòng)拼接塊并分割。取消讀取:記得在組件卸載或用戶導(dǎo)航時(shí)調(diào)用
reader.cancel(),避免后臺繼續(xù)下載。
總結(jié)
- 核心本質(zhì):Fetch 流式是 Fetch API 結(jié)合 HTTP Chunked 分塊傳輸,通過
response.body(ReadableStream)實(shí)現(xiàn)的逐塊數(shù)據(jù)處理能力; - 核心價(jià)值:解決大文件 / 實(shí)時(shí)數(shù)據(jù)一次性加載導(dǎo)致的「內(nèi)存溢出、頁面卡頓、等待時(shí)間長」問題;
- 核心用法:通過
reader.read()循環(huán)讀取數(shù)據(jù)塊,配合TextDecoder處理文本,或直接轉(zhuǎn)為 Blob 實(shí)現(xiàn)流式下載。
Fetch 流式是前端流式開發(fā)的基礎(chǔ)能力,也是面試中高頻問到的考點(diǎn),核心記住「response.body 是 ReadableStream」「逐塊讀取」「釋放讀取器」這三個(gè)關(guān)鍵點(diǎn)即可。
到此這篇關(guān)于普通Fetch和Fetch流式的區(qū)別詳解的文章就介紹到這了,更多相關(guān)普通Fetch和Fetch流式區(qū)別內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Bootstrap時(shí)間選擇器datetimepicker和daterangepicker使用實(shí)例解析
這篇文章主要為大家詳細(xì)解析了Bootstrap時(shí)間選擇器datetimepicker和daterangepicker使用實(shí)例,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-09-09
document.createElement()用法及注意事項(xiàng)(ff下不兼容)
今天處理了一個(gè)日期選擇器的ie和ff的兼容問題,本來這種情況就很難找錯(cuò)誤,找了好久才把錯(cuò)誤定位到j(luò)s中創(chuàng)建元素的方法document.createElement(),這個(gè)方法在ie下支持這樣創(chuàng)建元素2013-03-03
微信小程序 調(diào)用微信授權(quán)窗口相關(guān)問題解決
這篇文章主要介紹了微信小程序 調(diào)用微信授權(quán)窗口相關(guān)問題解決,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-07-07
JS函數(shù)內(nèi)部屬性之a(chǎn)rguments和this實(shí)例解析
在函數(shù)內(nèi)部,有兩個(gè)特殊的對象:arguments和this。這篇文章主要介紹了函數(shù)內(nèi)部屬性之a(chǎn)rguments和this ,需要的朋友可以參考下2018-10-10
JavaScript使用HTML5的window.postMessage實(shí)現(xiàn)跨域通信例子
這篇文章主要介紹了JavaScript使用HTML5的window.postMessage實(shí)現(xiàn)跨域通信例子,需要的朋友可以參考下2014-04-04
JavaScript trim 去除字符串空格的三種方法(附代碼詳解)
個(gè)人認(rèn)為最好的方法.采用的是正則表達(dá)式,這是最核心的原理.因?yàn)榭崭裼卸喾N形式。2010-05-05

