Saya memiliki tindakan Struts2 di sisi server untuk mengunduh file.
<action name="download" class="com.xxx.DownAction">
<result name="success" type="stream">
<param name="contentType">text/plain</param>
<param name="inputName">imageStream</param>
<param name="contentDisposition">attachment;filename={fileName}</param>
<param name="bufferSize">1024</param>
</result>
</action>
Namun ketika saya memanggil tindakan menggunakan jQuery:
$.post(
"/download.action",{
para1:value1,
para2:value2
....
},function(data){
console.info(data);
}
);
di Firebug saya melihat data diambil dengan aliran Biner . Saya bertanya-tanya bagaimana cara membuka jendela pengunduhan file yang dengannya pengguna dapat menyimpan file secara lokal?
Jawaban:
2019 pembaruan browser modern
Inilah pendekatan yang sekarang saya rekomendasikan dengan beberapa peringatan:
2012 Pendekatan berbasis jQuery / iframe / Cookie Asli
Kebiru - biruan benar tentang ini, Anda tidak dapat melakukannya melalui Ajax karena JavaScript tidak dapat menyimpan file secara langsung ke komputer pengguna (karena masalah keamanan). Sayangnya menunjuk URL jendela utama pada unduhan file Anda berarti Anda memiliki sedikit kendali atas apa yang dialami pengguna ketika unduhan file terjadi.
Saya membuat Unduhan File jQuery yang memungkinkan pengalaman "seperti Ajax" dengan unduhan file lengkap dengan panggilan balik OnSuccess dan OnFailure untuk memberikan pengalaman pengguna yang lebih baik. Lihatlah posting blog saya tentang masalah umum yang diselesaikan plugin dan beberapa cara untuk menggunakannya dan juga demo dari Unduhan File jQuery dalam aksi . Ini sumbernya
Berikut ini adalah contoh penggunaan sederhana menggunakan sumber plugin dengan janji. The halaman demo mencakup banyak lainnya, 'lebih baik UX' contoh juga.
Bergantung pada browser apa yang perlu Anda dukung, Anda mungkin dapat menggunakan https://github.com/eligrey/FileSaver.js/ yang memungkinkan kontrol lebih eksplisit daripada metode IFRAME yang digunakan oleh jQuery File Download.
sumber
Tidak ada yang memposting solusi @ Pekka ini ... jadi saya akan mempostingnya. Itu bisa membantu seseorang.
Anda tidak perlu melakukan ini melalui Ajax. Gunakan saja
sumber
window.open(<url>, '_blank');
untuk memastikan bahwa unduhan tidak akan menggantikan konten browser Anda saat ini (terlepas dari header Content-Disposition).POST
permintaan.Anda bisa menggunakan HTML5
NB: Data file yang dikembalikan HARUS base64 disandikan karena Anda tidak bisa menyandikan data biner JSON
Dalam
AJAX
tanggapan saya, saya memiliki struktur data yang terlihat seperti ini:Itu berarti bahwa saya dapat melakukan hal berikut untuk menyimpan file melalui AJAX
Function base64ToBlob diambil dari sini dan harus digunakan sesuai dengan fungsi ini
Ini bagus jika server Anda sedang membuang data yang disimpan. Namun, saya belum mengetahui bagaimana seseorang akan mengimplementasikan HTML4 fallback
sumber
a.click()
tampaknya tidak bekerja di firefox ... Setiap ide?a
dom ke agar kode ini bekerja dan / atau menghapusrevokeObjectURL
bagian:document.body.appendChild(a)
var bytechars = atob(base64)
itu melempar kesalahanJavaScript runtime error: InvalidCharacterError
. Saya menggunakan Chrome Versi 75.0.3770.142 tetapi saya tidak tahu, apa yang salah di sini.1. Framework agnostic: Servlet mengunduh file sebagai lampiran
2. Struts2 Framework: Tindakan mengunduh file sebagai lampiran
Akan lebih baik menggunakan
<s:a>
penunjuk tag dengan OGNL ke URL yang dibuat dengan<s:url>
tag:Dalam kasus di atas, Anda perlu menulis tajuk Content-Disposition ke respons , menentukan bahwa file tersebut perlu diunduh (
attachment
) dan tidak dibuka oleh browser (inline
). Anda perlu menentukan Tipe Konten juga, dan Anda mungkin ingin menambahkan nama dan panjang file (untuk membantu browser menggambar progressbar yang realistis).Misalnya, saat mengunduh ZIP:
Dengan Struts2 (kecuali jika Anda menggunakan Action sebagai Servlet, hack untuk streaming langsung , misalnya), Anda tidak perlu langsung menulis apa pun ke respons; cukup gunakan tipe hasil Stream dan konfigurasikan dalam struts.xml akan berfungsi: CONTOH
3. Framework agnostic (/ Struts2 framework): Servlet (/ Action) membuka file di dalam browser
Jika Anda ingin membuka file di dalam browser, alih-alih mengunduhnya, disposisi Konten harus diatur ke inline , tetapi target tidak boleh lokasi jendela saat ini; Anda harus menargetkan jendela baru yang dibuat oleh javascript,
<iframe>
halaman, atau jendela baru yang dibuat saat itu dengan "mendiskusikan" target = "_ blank":sumber
too long url
kesalahan.Cara sederhana untuk membuat browser mengunduh file adalah dengan membuat permintaan seperti itu:
Ini membuka pop up unduhan browser.
sumber
Saya telah membuat sedikit fungsi sebagai solusi penyelesaian masalah (terinspirasi oleh plugin @JohnCulviner):
Demo dengan acara klik:
sumber
Saya menghadapi masalah yang sama dan berhasil menyelesaikannya. Kasing saya adalah ini.
" Kirim data JSON ke server dan terima file excel. File excel itu dibuat oleh server dan dikembalikan sebagai respons kepada klien. Unduh respons itu sebagai file dengan nama khusus di browser "
Cuplikan di atas hanya melakukan yang berikut
Di sini kita perlu hati-hati mengatur beberapa hal di sisi server. Saya menetapkan beberapa header di Python Django HttpResponse. Anda perlu mengaturnya jika Anda menggunakan bahasa pemrograman lain.
Karena saya mengunduh xls (excel) di sini, saya menyesuaikan contentType dengan yang di atas. Anda perlu mengaturnya sesuai dengan jenis file Anda. Anda dapat menggunakan teknik ini untuk mengunduh semua jenis file.
sumber
HTMLAnchorElement.download
, saya berpikir untuk menggabungkannya dengan metode msSaveOrOpenBlob .Ok, berdasarkan kode ndpu di sini adalah versi ajax_download yang ditingkatkan (saya pikir); -
Gunakan ini seperti ini; -
Params dikirim sebagai params posting yang tepat seolah-olah berasal dari input daripada sebagai string json yang dikodekan seperti contoh sebelumnya.
CAVEAT: Waspadai potensi injeksi variabel pada formulir-formulir itu. Mungkin ada cara yang lebih aman untuk menyandikan variabel-variabel itu. Atau pertimbangkan untuk melarikan diri dari mereka.
sumber
Uncaught SecurityError: Blocked a frame with origin "http://foo.bar.com" from accessing a frame with origin "null". The frame requesting access has a protocol of "http", the frame being accessed has a protocol of "data". Protocols must match.
@ResourceMapping() public void downloadFile(final ResourceRequest request, final ResourceResponse response, @ModelAttribute("downForm") FormModel model)
tetapi tidak berfungsi ..Inilah yang saya lakukan, javascript dan html murni. Tidak mengujinya tetapi ini harus bekerja di semua browser.
sumber
sumber
download
atribut, sehingga file Anda akan berakhir dengan nama "Tidak Dikenal"Di Rails, saya melakukannya dengan cara ini:
Caranya adalah bagian window.location . Metode pengontrol terlihat seperti:
sumber
Gunakan
window.open
https://developer.mozilla.org/en-US/docs/Web/API/Window/openMisalnya, Anda dapat meletakkan baris kode ini di penangan klik:
Ini akan membuka tab baru (karena nama jendela '_blank') dan tab itu akan membuka URL.
Kode sisi server Anda juga harus memiliki sesuatu seperti ini:
Dan dengan demikian, browser harus meminta pengguna untuk menyimpan file ke disk, bukan hanya menunjukkan file kepada mereka. Ini juga akan secara otomatis menutup tab yang baru saja dibuka.
sumber
Saya mencoba mengunduh file CSV dan kemudian melakukan sesuatu setelah unduhan selesai. Jadi saya perlu menerapkan
callback
fungsi yang sesuai .Menggunakannya
window.location="..."
bukan ide yang baik karena saya tidak bisa mengoperasikan program setelah selesai mengunduh. Sesuatu seperti ini, ganti tajuk jadi itu bukan ide yang bagus.fetch
adalah alternatif yang baik namun tidak dapat mendukung IE 11 . Danwindow.URL.createObjectURL
tidak dapat mendukung IE 11. Anda dapat merujuk ini .Ini kode saya, mirip dengan kode Shahrukh Alam. Tetapi Anda harus berhati-hati yang
window.URL.createObjectURL
mungkin membuat kebocoran memori. Anda bisa merujuk ini . Ketika respons telah tiba, data akan disimpan ke dalam memori browser. Jadi sebelum Anda mengklika
tautan, file tersebut telah diunduh. Ini berarti Anda dapat melakukan apa saja setelah mengunduh.sumber
Cara MENGUNDUH file setelah menerimanya oleh AJAX
Lebih nyaman ketika file dibuat untuk waktu yang lama dan Anda harus menunjukkan PRELOADER
Contoh saat mengirimkan formulir web:
Fungsional opsional dikomentari untuk menyederhanakan contoh.
Tidak perlu membuat file sementara di server.
Pada jQuery v2.2.4 OK. Akan ada kesalahan pada versi lama:
sumber
filename.match(/filename=(.*)/)[1]
(tanpa tanda kutip ganda atau tanda tanya) - regex101.com/r/2AsD4y/2 . Namun, solusi Anda adalah satu-satunya solusi yang berfungsi setelah mencari banyak.Menambahkan beberapa hal lagi ke jawaban di atas untuk mengunduh file
Di bawah ini adalah beberapa kode pegas java yang menghasilkan byte Array
Sekarang dalam kode javascript menggunakan FileSaver.js, dapat mengunduh file dengan kode di bawah ini
Di atas akan mengunduh file
sumber
Ok jadi di sini adalah kode yang berfungsi ketika Menggunakan MVC dan Anda mendapatkan file Anda dari controller
katakanlah Anda memiliki byte array Anda menyatakan dan mengisi, satu-satunya hal yang perlu Anda lakukan adalah menggunakan fungsi File (menggunakan System.Web.Mvc)
dan kemudian, dalam pengontrol yang sama, tambahkan fungsi mereka
dan kemudian Anda akan dapat memanggil pengontrol Anda untuk mengunduh dan mendapatkan panggilan balik "sukses" atau "gagal"
sumber
Saya menemukan perbaikan bahwa sementara itu sebenarnya tidak menggunakan ajax itu memungkinkan Anda untuk menggunakan panggilan javascript untuk meminta unduhan dan kemudian mendapatkan panggilan balik ketika unduhan sebenarnya dimulai. Saya menemukan ini membantu jika tautan menjalankan skrip sisi server yang memerlukan sedikit waktu untuk menyusun file sebelum mengirimnya. sehingga Anda dapat memberi tahu mereka bahwa itu sedang diproses, dan kemudian ketika akhirnya mengirim file hapus pemberitahuan pemrosesan itu. itulah sebabnya saya ingin mencoba memuat file melalui ajax untuk memulainya sehingga saya dapat memiliki suatu peristiwa terjadi ketika file diminta dan yang lain ketika itu benar-benar mulai mengunduh.
js di halaman depan
iframe
lalu file lainnya:
Saya pikir ada cara untuk membaca mendapatkan data menggunakan js sehingga tidak diperlukan php. tapi saya tidak mengetahuinya begitu saja dan server yang saya gunakan mendukung php jadi ini bekerja untuk saya. pikir saya akan berbagi kalau-kalau itu membantu siapa pun.
sumber
Jika Anda ingin menggunakan Unduhan File jQuery, harap perhatikan ini untuk IE. Anda perlu mengatur ulang responsnya atau tidak akan mengunduh
Tindakan Anda dapat diterapkan
ServletResponseAware
untuk mengaksesgetServletResponse()
sumber
Sudah pasti Anda tidak bisa melakukannya melalui panggilan Ajax.
Namun, ada solusinya.
Langkah :
Jika Anda menggunakan form.submit () untuk mengunduh file, yang dapat Anda lakukan adalah:
Ini berguna jika Anda ingin memutuskan apakah file perlu diunduh atau tidak setelah membuat form.submit (), misalnya: ada kasus di form.submit (), pengecualian terjadi di sisi server dan sebagai gantinya crash, Anda mungkin perlu menampilkan pesan khusus di sisi klien, dalam hal ini implementasi ini mungkin membantu.
sumber
ada solusi lain untuk mengunduh halaman web di ajax. Tetapi saya merujuk ke halaman yang pertama-tama harus diproses dan kemudian diunduh.
Pertama, Anda perlu memisahkan pemrosesan halaman dari hasil unduhan.
1) Hanya penghitungan halaman yang dibuat dalam panggilan ajax.
Saya berharap solusi ini dapat bermanfaat bagi banyak orang, seperti juga bagi saya.
sumber
sumber
Itu berfungsi dengan sangat baik di browser apa pun (saya menggunakan asp.net core)
sumber
Saya berjuang dengan masalah ini untuk waktu yang lama. Akhirnya perpustakaan eksternal yang elegan yang disarankan di sini membantu saya.
sumber