參考:https://www.cnblogs.com/lxlx1798/articles/16969244.html 要麼使用流讀取器,要麼使用 Reponse 的方法來獲取結果,不能同時使用兩種方法來讀取相同的響應。 直接獲取: Response.blob() 方法返回一個 resolve 返回值 ...
參考:https://www.cnblogs.com/lxlx1798/articles/16969244.html
要麼使用流讀取器,要麼使用 Reponse 的方法來獲取結果,不能同時使用兩種方法來讀取相同的響應。
直接獲取:
Response.blob() 方法返回一個 resolve 返回值為 Blob 對象的 Promise
fetch(videoUrl).then(res => { const p = res.blob() return res.blob() }).then(blob => { const a = document.createElement("a"); a.style.display = 'none' document.body.append(a) const url = window.URL.createObjectURL(blob) a.href = url a.download = item.name a.click() document.body.removeChild(a) window.URL.revokeObjectURL(url) })
流讀取:
Response.body 是一個 ReadableStream 對象
ReadableStream.getReader() 創建流讀取器,並且會把流鎖定,預設返回的是 ReadableStreamDefaultReader 類型
The getReader()
method of the ReadableStream
interface creates a reader and locks the stream to it. While the stream is locked, no other reader can be acquired until this one is released.
response.headers.get('Content-Length') 得到響應的總長度
ReadableStreamDefaultReader.read() 方法得到一個 Promise 對象,可以獲取到流內部序列中的下一個分塊,迴圈調用直到完成,同時收集數據得到一個 Uint8Array 數組
最後轉換成 Blob 就可以完成下載了
const videoUrl = 'video url'
const response = await fetch(videoUrl) const reader = response.body.getReader() const contentLength = +response.headers.get('Content-Length') let receivedLength = 0 let chunks = [] while (true) { const { done, value } = await reader.read(); if (done) { break } chunks.push(value) receivedLength += value.length // 下載進度 console.log(`Reveived ${receivedLength} of ${contentLength}`) } const a = document.createElement("a"); a.style.display = 'none' document.body.append(a) const url = window.URL.createObjectURL(new Blob(chunks, { type: 'video/mp4'} )) a.href = url a.download = item.name a.click() document.body.removeChild(a) window.URL.revokeObjectURL(url)
用到的一些方法:
fetch()
The global fetch()
method starts the process of fetching a resource from the network, returning a promise which is fulfilled once the response is available.
The promise resolves to the Response
object representing the response to your request.
A fetch()
promise only rejects when a network error is encountered (which is usually when there's a permissions issue or similar). A fetch()
promise does not reject on HTTP errors (404
, etc.). Instead, a then()
handler must check the Response.ok
and/or Response.status
properties.
WindowOrWorkerGlobalScope
is implemented by both Window
and WorkerGlobalScope
, which means that the fetch()
method is available in pretty much any context in which you might want to fetch resources.
The fetch()
method is controlled by the connect-src
directive of Content Security Policy rather than the directive of the resources it's retrieving.
ReadableStream.getReader()
The getReader()
method of the ReadableStream
interface creates a reader and locks the stream to it. While the stream is locked, no other reader can be acquired until this one is released.
ReadableStreamDefaultReader.read()
The read()
method of the ReadableStreamDefaultReader
interface returns a Promise
providing access to the next chunk in the stream's internal queue.
URL.createObjectURL()
The URL.createObjectURL()
static method creates a string containing a URL representing the object given in the parameter.
The URL lifetime is tied to the document
in the window on which it was created. The new object URL represents the specified File
object or Blob
object.
To release an object URL, call revokeObjectURL()
.
URL.revokeObjectURL()
The URL.revokeObjectURL()
static method releases an existing object URL which was previously created by calling URL.createObjectURL()
.
Call this method when you've finished using an object URL to let the browser know not to keep the reference to the file any longer.