从此
📄文章 #️⃣专题 🌐酷站 👨‍💻技术 📺 📱

🏠 » 📄文章 » 内容

 欢迎来访!

fetch 流式请求 body 支持 ReadableStream 上传 stream 下载进度

🕗2025-01-30👁️1

fetch API 流式请求 body 支持 ReadableStream 上传 stream 下载进度

async function main() {
    const blobOrFile= new Blob([new Uint8Array(10 * 1024 * 1024)]); // any Blob, including a File
    const uploadProgress = document.getElementById("upload-progress");
    const downloadProgress = document.getElementById("download-progress");
  
    const totalBytes = blobOrFile.size;
    let bytesUploaded = 0;
  
    // Use a custom TransformStream to track upload progress
    const progressTrackingStream = new TransformStream({
      transform(chunk, controller) {
        controller.enqueue(chunk);
        bytesUploaded += chunk.byteLength;
        console.log("upload progress:", bytesUploaded / totalBytes);
        uploadProgress.value = bytesUploaded / totalBytes;
      },
      flush(controller) {
        console.log("completed stream");
      },
    });
    const response = await fetch("https://httpbin.org/put", {
      method: "PUT",
      headers: {
        "Content-Type": "application/octet-stream"
      },
      body: blobOrFile.stream().pipeThrough(progressTrackingStream),
      duplex: "half",
    });
    
    // After the initial response headers have been received, display download progress for the response body
    let success = true;
    const totalDownloadBytes = response.headers.get("content-length");
    let bytesDownloaded = 0;
    const reader = response.body.getReader();
    while (true) {
      try {
        const { value, done } = await reader.read();
        if (done) {
          break;
        }
        bytesDownloaded += value.length;
        if (totalDownloadBytes != undefined) {
          console.log("download progress:", bytesDownloaded / totalDownloadBytes);
          downloadProgress.value = bytesDownloaded / totalDownloadBytes;
        } else {
          console.log("download progress:", bytesDownloaded, ", unknown total");
        }
      } catch (error) {
        console.error("error:", error);
        success = false;
        break;
      }
    }
    
    console.log("success:", success);
  }
main().catch(console.error);