Saya kesulitan menemukan dokumentasi atau contoh penerapan indikator kemajuan upload menggunakan fetch .
Ini adalah satu-satunya referensi yang saya temukan sejauh ini , yang menyatakan:
Peristiwa kemajuan adalah fitur tingkat tinggi yang tidak akan datang untuk saat ini. Anda dapat membuatnya sendiri dengan melihat
Content-Length
header dan menggunakan aliran pass-through untuk memantau byte yang diterima.Ini berarti Anda dapat menangani respons secara eksplisit tanpa
Content-Length
perbedaan. Dan tentu saja, bahkan jikaContent-Length
ada itu bisa menjadi kebohongan. Dengan aliran Anda dapat menangani kebohongan ini sesuka Anda.
Bagaimana saya menulis "aliran pass-through untuk memantau byte" yang dikirim? Jika ada perbedaan, saya mencoba melakukan ini untuk mendukung unggahan gambar dari browser ke Cloudinary .
CATATAN : Saya tidak tertarik dengan pustaka Cloudinary JS , karena bergantung pada jQuery dan aplikasi saya tidak. Saya hanya tertarik pada pemrosesan streaming yang diperlukan untuk melakukan ini dengan javascript asli dan fetch
polyfill Github .
sumber
Jawaban:
Aliran mulai mendarat di platform web ( https://jakearchibald.com/2016/streams-ftw/ ) tetapi ini masih awal.
Anda akan segera dapat menyediakan aliran sebagai isi permintaan, tetapi pertanyaan terbukanya adalah apakah konsumsi aliran itu terkait dengan byte yang diunggah.
Pengalihan tertentu dapat mengakibatkan data dikirim ulang ke lokasi baru, tetapi aliran tidak dapat "dimulai ulang". Kita dapat memperbaikinya dengan mengubah body menjadi callback yang dapat dipanggil berkali-kali, tetapi kita perlu memastikan bahwa mengungkapkan jumlah pengalihan bukanlah kebocoran keamanan, karena ini akan menjadi pertama kalinya di platform JS bisa deteksi itu.
Beberapa mempertanyakan apakah masuk akal untuk menautkan konsumsi aliran ke byte yang diunggah.
Singkat cerita: ini belum memungkinkan, tetapi di masa mendatang ini akan ditangani baik oleh streaming, atau semacam panggilan balik tingkat tinggi yang diteruskan ke
fetch()
.sumber
Solusi saya adalah menggunakan axios , yang mendukung ini dengan cukup baik:
Saya punya contoh untuk menggunakan ini dalam bereaksi di github.
sumber
axios
menggunakanfetch
atauXMLHttpRequest
under-the-hood?axios
tidak digunakan difetch
bawah tenda, dan tidak memiliki dukungan seperti itu. Saya benar-benar mengarangnya sekarang untuk mereka.Saya tidak berpikir itu mungkin. Draf tersebut menyatakan:
(jawaban lama):
Contoh pertama di bab Fetch API memberikan beberapa wawasan tentang cara:
Selain dari penggunaan
Promise
antipattern konstruktor , Anda dapat melihatnyaresponse.body
Stream dari mana Anda dapat membaca byte demi byte menggunakan Pembaca, dan Anda dapat mengaktifkan acara atau melakukan apa pun yang Anda suka (misalnya mencatat kemajuan) untuk masing-masing.Namun, spesifikasi Streams tampaknya belum selesai, dan saya tidak tahu apakah ini sudah berfungsi dalam implementasi pengambilan apa pun.
sumber
fetch
. Saya tertarik dengan indikator kemajuan untuk mengupload file.Promise
konstruktor tidak diperlukan.Response.body.getReader()
mengembalikan aPromise
. Lihat Cara mengatasi Kesalahan Rentang yang Tidak Tertangkap saat mengunduh json ukuran besargetReader
tidak mengembalikan janji. Tidak tahu apa hubungannya ini dengan kiriman yang Anda tautkan..getReader()
's.read()
metode mengembalikanPromise
. Demikian yang ingin disampaikan. Tautan ini untuk menyinggung premis bahwa jika kemajuan dapat diperiksa untuk pengunduhan, kemajuan dapat diperiksa untuk pengunggahan. Kumpulkan pola yang mengembalikan hasil yang diharapkan, pada tingkat yang cukup; itu kemajuan untukfetch()
mengunggah. Belum menemukan cara keecho
suatuBlob
atauFile
objek di jsfiddle, mungkin melewatkan sesuatu yang sederhana. Mengujilocalhost
unggahan file dengan sangat cepat, tanpa meniru kondisi jaringan; meski baru ingatNetwork throttling
.Pembaruan: karena jawaban yang diterima mengatakan tidak mungkin sekarang. tetapi kode di bawah ini menangani masalah kami untuk beberapa saat. Saya harus menambahkan bahwa setidaknya kita harus beralih menggunakan perpustakaan yang didasarkan pada XMLHttpRequest.
berkat tautan ini: https://jakearchibald.com/2016/streams-ftw/
sumber
content-length
! == panjang badan. Ketika kompresi http digunakan (umum untuk unduhan besar), panjang konten adalah ukuran setelah kompresi http, sedangkan panjang adalah ukuran setelah file diekstraksi.Karena tidak ada jawaban yang memecahkan masalah.
Demi penerapan, Anda dapat mendeteksi kecepatan unggah dengan potongan awal kecil dari ukuran yang diketahui dan waktu unggah dapat dihitung dengan panjang konten / kecepatan unggah. Anda dapat menggunakan waktu ini sebagai perkiraan.
sumber
Solusi yang mungkin adalah dengan menggunakan
new Request()
konstruktor lalu memeriksaRequest.bodyUsed
Boolean
atributuntuk menentukan apakah aliran
distributed
Kembalikan
fetch()
Promise
dari dalam.then()
berantai ke.read()
panggilan rekursif dariReadableStream
saatRequest.bodyUsed
sama dengantrue
.Catatan, pendekatan ini tidak membaca byte
Request.body
sebagai byte dialirkan ke titik akhir. Selain itu, unggahan dapat diselesaikan dengan baik sebelum tanggapan apa pun dikembalikan sepenuhnya ke browser.sumber
sumber
Bagian kuncinya adalah ReadableStream ≪ obj_response .body≫.
Sampel:
Anda dapat menguji menjalankannya di halaman besar misalnya https://html.spec.whatwg.org/ dan https://html.spec.whatwg.org/print.pdf . CtrlShiftJ dan muat kodenya.
(Diuji di Chrome.)
sumber