Saya punya masalah dalam mengirim file ke skrip PHP di sisi server menggunakan fungsi ajax jQuery. Mungkin untuk mendapatkan File-List dengan $('#fileinput').attr('files')
tetapi bagaimana mungkin untuk mengirim data ini ke server? Array yang dihasilkan ( $_POST
) pada script-serveride php adalah 0 ( NULL
) saat menggunakan input file.
Saya tahu itu mungkin (meskipun saya tidak menemukan solusi jQuery sampai sekarang, hanya kode Prototye ( http://webreflection.blogspot.com/2009/03/safari-4-multiple-upload-with-progress.html ) ).
Ini tampaknya relatif baru, jadi tolong jangan menyebutkan bahwa pengunggahan file tidak mungkin dilakukan melalui XHR / Ajax, karena itu pasti berfungsi.
Saya membutuhkan fungsionalitas di Safari 5, FF dan Chrome akan menyenangkan tetapi tidak penting.
Kode saya untuk saat ini adalah:
$.ajax({
url: 'php/upload.php',
data: $('#file').attr('files'),
cache: false,
contentType: 'multipart/form-data',
processData: false,
type: 'POST',
success: function(data){
alert(data);
}
});
$(':file')
untuk memilih semua file input. Itu hanya sedikit lebih sederhana.Jawaban:
Dimulai dengan Safari 5 / Firefox 4, paling mudah menggunakan
FormData
kelas:Jadi sekarang Anda memiliki
FormData
objek, siap dikirim bersama dengan XMLHttpRequest.Sangat penting bagi Anda untuk mengatur
contentType
opsifalse
, memaksa jQuery untuk tidak menambahkanContent-Type
header untuk Anda, jika tidak, string batas akan hilang darinya. Selain itu, Anda harus membiarkanprocessData
flag disetel ke false, jika tidak, jQuery akan mencoba mengubah AndaFormData
menjadi string, yang akan gagal.Anda sekarang dapat mengambil file dalam PHP menggunakan:
(Hanya ada satu file,,
file-0
kecuali jika Anda menentukanmultiple
atribut pada input file Anda, dalam hal ini, angkanya akan bertambah dengan setiap file.)Menggunakan emulasi FormData untuk browser yang lebih lama
Buat FormData dari formulir yang ada
Alih-alih secara manual mengulangi file, objek FormData juga dapat dibuat dengan konten objek formulir yang ada:
Gunakan array asli PHP alih-alih penghitung
Cukup beri nama elemen file Anda sama dan akhiri nama dalam tanda kurung:
$_FILES['file']
maka akan menjadi array yang berisi bidang unggahan file untuk setiap file yang diunggah. Saya sebenarnya merekomendasikan ini di atas solusi awal saya karena lebih mudah untuk beralih.sumber
data.fake
dan mengaturcontentType
properti secara manual serta mengganti xhr untuk digunakansendAsBinary()
.jQuery
atauFormData
kelas dan Anda bertanya kepada saya dalam konteks pertanyaan khusus untuk jQuery dan jawaban khusus untuk menggunakan FormData? Maaf, tapi saya rasa saya tidak bisa membantu Anda di sana ...application/x-www-form-urlencoded
. Apakah ada cara untuk menggunakannyamultipart/form-data
?multipart/form-data
. Menggunakanapplication/x-www-form-urlencoded
tidak akan berhasil.Hanya ingin menambahkan sedikit jawaban Raphael yang luar biasa. Berikut cara mendapatkan PHP untuk menghasilkan yang sama
$_FILES
, terlepas dari apakah Anda menggunakan JavaScript untuk mengirim.Bentuk HTML:
PHP menghasilkan ini
$_FILES
, ketika dikirimkan tanpa JavaScript:Jika Anda melakukan peningkatan progresif, gunakan Raphael's JS untuk mengirim file ...
... beginilah bentuk
$_FILES
array PHP , setelah menggunakan JavaScript itu untuk mengirim:Itu array yang bagus, dan sebenarnya apa yang ditransformasikan oleh beberapa orang
$_FILES
, tetapi saya merasa bermanfaat untuk bekerja dengan yang sama$_FILES
, terlepas dari apakah JavaScript digunakan untuk mengirim. Jadi, berikut adalah beberapa perubahan kecil pada JS:(14 April 2017 sunting: Saya menghapus elemen formulir dari konstruktor FormData () - yang memperbaiki kode ini di Safari.)
Kode itu melakukan dua hal.
input
atribut nama secara otomatis, membuat HTML lebih mudah dikelola. Sekarang, selamaform
memiliki putImages kelas, semua hal lain diurus secara otomatis. Artinya,input
tidak perlu memiliki nama khusus.Dengan perubahan ini, mengirimkan dengan JavaScript sekarang menghasilkan
$_FILES
array yang sama persis seperti mengirimkan dengan HTML sederhana.sumber
Lihatlah kode saya, itu berfungsi untuk saya
sumber
Saya baru saja membangun fungsi ini berdasarkan beberapa info yang saya baca.
Gunakan itu seperti menggunakan
.serialize()
, bukan hanya menempatkan.serializefiles();
.Bekerja di sini dalam ujian saya.
sumber
var data = $("#avatar-form").serializefiles();
mengirimkan ini melalui parameter data ajax dan menganalisis dengan tangguh ekspres:form.parse(req, function(err, fields, files){
terima kasih untuk potongan kode itu :)Jika formulir Anda didefinisikan dalam HTML Anda, lebih mudah untuk memasukkan formulir ke konstruktor daripada untuk iterate dan menambahkan gambar.
sumber
Jawaban Devin Venable dekat dengan apa yang saya inginkan, tetapi saya menginginkan yang akan bekerja pada banyak formulir, dan menggunakan tindakan yang sudah ditentukan dalam formulir sehingga setiap file akan pergi ke tempat yang tepat.
Saya juga ingin menggunakan metode on () jQuery sehingga saya bisa menghindari penggunaan .ready ().
Itu membuat saya seperti ini: (ganti formSelector dengan pemilih jQuery Anda)
sumber
Saat ini Anda bahkan tidak perlu jQuery :) mengambil tabel dukungan API
sumber
fetch
silakan lihat kompatibilitas: developer.mozilla.org/en-US/docs/Web/API/…:-|
Kelas FormData berfungsi, namun di iOS Safari (setidaknya di iPhone) saya tidak dapat menggunakan solusi Raphael Schweikert seperti apa adanya.
Mozilla Dev memiliki halaman yang bagus tentang memanipulasi objek FormData .
Jadi, tambahkan formulir kosong di suatu tempat di halaman Anda, tentukan enctype:
Lalu, buat objek FormData sebagai:
dan lanjutkan seperti dalam kode Raphael .
sumber
Satu gotcha yang saya temui hari ini saya pikir layak untuk ditunjukkan terkait dengan masalah ini: jika url untuk panggilan ajax dialihkan maka header untuk tipe konten: 'multipart / formulir-data' dapat hilang.
Misalnya, saya memposting ke http://server.com/context?param=x
Di tab jaringan Chrome saya melihat header multi-bagian yang benar untuk permintaan ini, tetapi kemudian 302 redirect ke http://server.com/context/?param=x (perhatikan garis miring setelah konteks)
Selama pengalihan header multi bagian hilang. Pastikan permintaan tidak dialihkan jika solusi ini tidak berhasil untuk Anda.
sumber
Semua solusi di atas terlihat bagus dan elegan, tetapi objek FormData () tidak mengharapkan parameter apa pun, tetapi gunakan append () setelah instantiate, seperti apa yang ditulis di atas:
formData.append (val.name, val.value);
sumber
Jika input file
name
menunjukkan array dan flagmultiple
, dan Anda menguraikan keseluruhanform
denganFormData
, tidak perlu secara iteratifappend()
file input.FormData
akan secara otomatis menangani banyak file.Perhatikan bahwa reguler
button type="button"
digunakan, bukantype="submit"
. Ini menunjukkan bahwa tidak ada ketergantungan pada penggunaansubmit
untuk mendapatkan fungsionalitas ini.$_FILES
Entri yang dihasilkan seperti ini di alat dev Chrome:Catatan: Ada kasus di mana beberapa gambar akan diunggah dengan baik ketika diunggah sebagai satu file, tetapi mereka akan gagal ketika diunggah dalam satu set beberapa file. Gejalanya adalah bahwa laporan PHP kosong
$_POST
dan$_FILES
tanpa AJAX membuat kesalahan. Masalah terjadi dengan Chrome 75.0.3770.100 dan PHP 7.0. Tampaknya hanya terjadi dengan 1 dari beberapa lusin gambar dalam set pengujian saya.sumber
Versi IE yang lebih lama tidak mendukung FormData (Daftar dukungan browser lengkap untuk FormData ada di sini: https://developer.mozilla.org/en-US/docs/Web/API/FormData ).
Entah Anda dapat menggunakan plugin jquery (Sebagai contoh, http://malsup.com/jquery/form/#code-samples ) atau, Anda dapat menggunakan solusi berbasis IFrame untuk mengirim data formulir multi-bagian melalui ajax: https: // developer. mozilla.org/en-US/docs/Learn/HTML/Forms/Sending_forms_through_JavaScript
sumber
PHP
jQuery dan Form HTML
sumber
sumber