Saya memiliki halaman yang memungkinkan pengguna untuk mengunduh file yang dihasilkan secara dinamis. Butuh waktu lama untuk menghasilkan, jadi saya ingin menunjukkan indikator "menunggu". Masalahnya adalah, saya tidak tahu cara mendeteksi kapan browser menerima file, jadi saya bisa menyembunyikan indikator.
Saya membuat permintaan dalam bentuk tersembunyi, yang POST ke server, dan menargetkan iframe tersembunyi untuk hasilnya. Ini jadi saya tidak mengganti seluruh jendela browser dengan hasilnya. Saya mendengarkan acara "memuat" di iframe, dengan harapan bahwa itu akan menyala ketika unduhan selesai.
Saya mengembalikan header "Content-Disposition: attachment" dengan file, yang menyebabkan browser menampilkan dialog "Simpan". Tetapi peramban tidak memecat acara "memuat" di iframe.
Salah satu pendekatan yang saya coba adalah menggunakan respons multi-bagian. Jadi itu akan mengirim file HTML kosong, serta file yang dapat diunduh terlampir. Sebagai contoh:
Content-type: multipart/x-mixed-replace;boundary="abcde"
--abcde
Content-type: text/html
--abcde
Content-type: application/vnd.fdf
Content-Disposition: attachment; filename=foo.fdf
file-content
--abcde
Ini berfungsi di Firefox; ia menerima file HTML kosong, menyalakan acara "memuat", lalu menampilkan dialog "Simpan" untuk file yang dapat diunduh. Tetapi gagal pada IE dan Safari; IE memecat acara "memuat" tetapi tidak mengunduh file, dan Safari mengunduh file (dengan nama dan tipe konten yang salah), dan tidak memecat acara "memuat".
Pendekatan yang berbeda mungkin untuk membuat panggilan untuk memulai pembuatan file, lalu polling server sampai siap, lalu unduh file yang sudah dibuat. Tapi saya lebih suka menghindari membuat file sementara di server.
Adakah yang punya ide yang lebih baik?
sumber
Jawaban:
Salah satu solusi yang mungkin menggunakan JavaScript pada klien.
Algoritme klien:
Algoritma server:
Kode sumber klien (JavaScript):
Contoh kode server (PHP):
Dimana:
sumber
Solusi satu baris yang sangat sederhana (dan lumpuh) adalah menggunakan
window.onblur()
acara tersebut untuk menutup dialog pemuatan. Tentu saja, jika terlalu lama dan pengguna memutuskan untuk melakukan sesuatu yang lain (seperti membaca email) dialog pemuatan akan ditutup.sumber
onbeforeunload
Terima kasih.utas lama, saya tahu ...
tetapi mereka, yang dipimpin di sini oleh google mungkin tertarik pada solusi saya. itu sangat sederhana, namun dapat diandalkan. dan memungkinkan untuk menampilkan pesan kemajuan nyata (dan dapat dengan mudah dicolokkan ke proses yang ada):
skrip yang memproses (masalah saya adalah: mengambil file melalui http dan mengirimkannya sebagai zip) menulis status ke sesi.
statusnya disurvei dan ditampilkan setiap detik. itu saja (ok, tidak. Anda harus mengurus banyak detail [mis. unduhan bersamaan], tapi ini tempat yang bagus untuk memulai ;-)).
halaman unduhan:
getstatus.php
unduh.php
sumber
.each()
untuk pendaftaran acara. katakan saja$('a.download').click()
setTimeout('getstatus()', 1000);
. Gunakan fn secara langsung:setTimeout(getstatus, 1000);
Saya menggunakan yang berikut ini untuk mengunduh gumpalan dan mencabut url-objek setelah unduhan. ini bekerja di chrome dan firefox!
setelah dialog unduhan file ditutup, jendela mendapatkan kembali fokusnya sehingga acara fokus dipicu.
sumber
Berdasarkan contoh Elmer, saya sudah menyiapkan solusi sendiri. Setelah elemen diklik dengan kelas unduhan yang ditentukan, ia memungkinkan untuk menampilkan pesan khusus di layar. Saya telah menggunakan pemicu fokus untuk menyembunyikan pesan.
JavaScript
HTML
Sekarang Anda harus menerapkan elemen apa pun untuk mengunduh:
atau
Setelah setiap klik unduhan, Anda akan melihat pesan yang dibuat oleh laporan Anda, harap tunggu ...
sumber
Saya menulis kelas JavaScript sederhana yang menerapkan teknik yang mirip dengan yang dijelaskan dalam jawaban bulltorious . Semoga bermanfaat bagi seseorang di sini. Proyek GitHub disebut response-monitor.js
Secara default menggunakan spin.js sebagai indikator menunggu tetapi juga menyediakan serangkaian panggilan balik untuk penerapan indikator khusus.
JQuery didukung tetapi tidak diperlukan.
Fitur-fitur penting
Contoh penggunaan
HTML
Klien (JavaScript biasa)
Klien (JQuery)
Klien dengan panggilan balik (JQuery)
Server (PHP)
Untuk lebih banyak contoh, periksa folder contoh di repositori.
sumber
Saya sangat terlambat ke pesta tetapi saya akan menempatkan ini di sini jika orang lain ingin tahu solusi saya:
Saya memiliki perjuangan nyata dengan masalah yang tepat ini, tetapi saya menemukan solusi yang layak menggunakan iframe (saya tahu, saya tahu. Ini mengerikan tetapi bekerja untuk masalah sederhana yang saya punya)
Saya memiliki halaman html yang meluncurkan skrip php terpisah yang menghasilkan file dan kemudian mengunduhnya. Pada halaman html, saya menggunakan jquery berikut di header html (Anda juga harus menyertakan perpustakaan jquery):
Di your_download_script.php, miliki yang berikut ini:
Untuk memecah ini, jquery pertama meluncurkan skrip php Anda dalam iframe. Iframe dimuat setelah file dibuat. Kemudian jquery meluncurkan skrip lagi dengan variabel permintaan yang memberitahu skrip untuk mengunduh file.
Alasan Anda tidak dapat melakukan pengunduhan dan pembuatan file sekaligus adalah karena fungsi php header (). Jika Anda menggunakan tajuk (), Anda mengubah skrip ke sesuatu selain halaman web dan jquery tidak akan pernah mengenali skrip unduhan sebagai 'dimuat'. Saya tahu ini mungkin tidak selalu mendeteksi ketika browser menerima file tetapi masalah Anda terdengar mirip dengan milikku.
sumber
Jika Anda streaming file yang Anda hasilkan secara dinamis, dan juga memiliki perpustakaan perpesanan server-ke-klien yang realtime, Anda dapat memberi tahu klien Anda dengan mudah.
Perpustakaan perpesanan server-ke-klien yang saya sukai dan rekomendasikan adalah Socket.io (via Node.js). Setelah skrip server Anda selesai menghasilkan file yang sedang di-stream untuk mengunduh baris terakhir Anda di skrip itu dapat memancarkan pesan ke Socket.io yang mengirimkan pemberitahuan kepada klien. Pada klien, Socket.io mendengarkan pesan masuk yang dipancarkan dari server dan memungkinkan Anda untuk menindaklanjutinya. Manfaat menggunakan metode ini dibandingkan yang lain adalah Anda dapat mendeteksi acara selesai "benar" setelah streaming selesai.
Misalnya, Anda dapat menampilkan indikator sibuk Anda setelah tautan unduhan diklik, mengalirkan file Anda, mengirimkan pesan ke Socket.io dari server di baris terakhir skrip streaming Anda, dengarkan klien untuk pemberitahuan, terima pemberitahuan dan perbarui UI Anda dengan menyembunyikan indikator sibuk.
Saya menyadari sebagian besar orang membaca jawaban untuk pertanyaan ini mungkin tidak memiliki jenis pengaturan ini, tetapi saya telah menggunakan solusi tepat ini untuk efek yang besar dalam proyek saya sendiri dan itu bekerja dengan sangat baik.
Socket.io sangat mudah dipasang dan digunakan. Lihat lebih lanjut: http://socket.io/
sumber
"Bagaimana cara mendeteksi ketika browser menerima unduhan file?"
Saya menghadapi masalah yang sama dengan konfigurasi itu:
struts 1.2.9
jquery-1.3.2.
jquery-ui-1.7.1.custom
IE 11
java 5
Solusi saya dengan cookie:
- Sisi klien:
Saat mengirimkan formulir Anda, panggil fungsi javascript Anda untuk menyembunyikan halaman Anda dan memuat spinner yang menunggu Anda
Kemudian, panggil fungsi yang akan memeriksa setiap 500 ms apakah cookie berasal dari server.
Jika cookie ditemukan, berhenti memeriksa setiap 500ms, kedaluwarsa cookie dan panggil fungsi Anda untuk kembali ke halaman Anda dan menghapus spinner yang menunggu ( removeWaitingSpinner () ). Penting untuk kedaluwarsa cookie jika Anda ingin dapat mengunduh file lain lagi!
- Sisi server:
Di akhir proses server Anda, tambahkan cookie ke respons. Cookie itu akan dikirim ke klien ketika file Anda siap untuk diunduh.
Saya berharap dapat membantu seseorang!
sumber
Ketika pengguna memicu pembuatan file, Anda bisa menetapkan ID unik untuk "unduhan" itu, dan mengirim pengguna ke halaman yang menyegarkan (atau memeriksa dengan AJAX) setiap beberapa detik. Setelah file selesai, simpan di bawah ID unik yang sama dan ...
Kemudian Anda dapat melewati seluruh kekacauan iframe / waiting / browserwindow, namun memiliki solusi yang sangat elegan.
sumber
Jika Anda tidak ingin membuat dan menyimpan file di server, apakah Anda bersedia menyimpan statusnya, misal file-in-progress, file-complete? Halaman "menunggu" Anda dapat mengumpulkan informasi dari server untuk mengetahui kapan pembuatan file selesai. Anda tidak akan tahu pasti bahwa browser memulai unduhan tetapi Anda akan memiliki kepercayaan diri.
sumber
Saya baru saja mengalami masalah yang sama persis ini. Solusi saya adalah menggunakan file sementara karena saya sudah menghasilkan banyak file sementara. Formulir dikirimkan dengan:
Di akhir skrip yang menghasilkan file yang saya miliki:
Ini akan menyebabkan acara pemuatan di iframe dipecat. Kemudian pesan tunggu ditutup dan unduhan file akan dimulai. Diuji pada IE7 dan Firefox.
sumber
Dalam pengalaman saya, ada dua cara untuk menangani ini:
sumber
Salam, saya tahu bahwa topiknya sudah lama tetapi saya meninggalkan solusi yang saya lihat di tempat lain dan berhasil:
Anda bisa menggunakannya:
sumber
Jika Anda telah mengunduh file, yang disimpan, sebagai lawan berada di dalam dokumen, tidak ada cara untuk menentukan kapan unduhan selesai, karena itu bukan dalam lingkup dokumen saat ini, tetapi merupakan proses terpisah di browser.
sumber
Pertanyaannya adalah memiliki indikator 'menunggu' saat file dibuat dan kemudian kembali normal setelah file diunduh. Cara saya suka melakukan ini adalah menggunakan iFrame tersembunyi dan mengaitkan aktivitas muatan frame untuk memberi tahu halaman saya saat unduhan dimulai. TAPI onload tidak diaktifkan di IE untuk unduhan file (seperti dengan token header lampiran). Polling server berfungsi, tapi saya tidak suka kompleksitas ekstra. Jadi inilah yang saya lakukan:
Penafian, jangan lakukan ini di situs yang sibuk, karena caching bisa bertambah. Tapi sungguh, jika situs Anda yang sibuk proses yang berjalan lama akan membuat Anda kelaparan utas.
Inilah yang terlihat seperti codebehind, yang benar-benar Anda butuhkan.
sumber
Solusi cepat jika Anda hanya ingin menampilkan pesan atau loader gif sampai dialog unduhan ditampilkan adalah meletakkan pesan dalam wadah tersembunyi dan ketika Anda mengklik tombol yang menghasilkan file yang akan diunduh, Anda membuat wadah tersebut terlihat. Kemudian gunakan jquery atau javascript untuk menangkap acara fokus tombol untuk menyembunyikan wadah yang berisi pesan
sumber
Jika Xmlhttprequest dengan blob bukan opsi maka Anda dapat membuka file Anda di jendela baru dan memeriksa apakah ada elemen yang terisi dalam jendela itu dengan interval.
sumber
Contoh Java / Spring ini mendeteksi akhir suatu Unduhan, yang pada saat itu menyembunyikan indikator "Memuat ...".
Pendekatan: Di sisi JS, atur Cookie dengan Max Expiration Age of 2 min, dan polling setiap detik untuk cookie expiration . Kemudian sisi server menimpa cookie ini dengan usia kedaluwarsa yang lebih awal - penyelesaian proses server. Segera setelah cookie kedaluwarsa terdeteksi di polling JS, "Memuat ..." disembunyikan.
Sisi JS
Sisi Server Java / Musim Semi
sumber
myCookie.setPath("/"); response.addCookie(myCookie);
Primefaces juga menggunakan polling cookie
https://github.com/primefaces/primefaces/blob/32bb00299d00e50b2cba430638468a4145f4edb0/src/main/resources/META-INF/resources/primefaces/core/core.js#L458
sumber
Buat iframe saat tombol / tautan diklik dan tambahkan ini ke badan.
Buat iframe dengan penundaan dan hapus setelah diunduh.
sumber