Events progress 用於描述資源加載的進度,主要由 AJAX 請求, <img>
, <audio>
, <video>
, <style>
, <link>
…等外部資源的加載觸發。
主要包含以下幾種事件:
比如下面這個例子:
前面有提到 Progress event 其中包含 progress 事件是在外部資源加載過程中不斷觸發,所以我們要計算請求的當前進度就需要透過監聽 progress 事件來實現。
progress 事件的返回值是一個物件,物件中包括 loaded
和 total
這兩個值,loaded
代表當前請求的 byte 數,total
則是總共的 byte 數。
物件中還有一個 lengthComputable
,如果 lengthComputable 為 true 代表該資源有可計算的長度,此時才能計算請求進度,如果為 false 就無法計算。
簡單的例子如下:
而如果要監聽上傳進度,只需要在 xhr.addEventListener 中間加上 upload
就可以,其餘寫法都一樣:
axios 本身有提供 onDownloadProgress
方法來獲取 progress event 物件,就不需要再自己寫事件監聽了:
fetch 無法直接獲取請求進度,不過 fetch response 裡有一個 body,這個 body 是一個可讀流,可以藉由可讀流的 getReader()
方法拿到一個讀取器(reader),將讀取器中的 value
一直累加就是當前已加載的資料量(byte),直到 done
為 true 時代表請求完成。
至於總資料量,直接從 response 獲取 content-length
即可。
fetch 目前無法計算上傳進度
這是因為 response headers 沒有 Content-Length 而導致,可能是因為檔案被分塊發送或者使用gzip壓縮(Content-Encoding: gzip
)。
解決方法就只有請後端在 response headers 加上 Content-Length
了。