jQuery.ajax ile multipart/formdata gönderme
jQuery'nin ajax fonksiyonunu kullanarak sunucu tarafındaki bir PHP betiğine dosya gönderirken sorun yaşıyorum.
Dosya Listesini $('#fileinput').attr('files')
ile almak mümkün, ancak bu Veriyi sunucuya göndermek nasıl mümkün olabilir? Dosya girişi kullanıldığında sunucu tarafındaki php komut dosyasında elde edilen dizi ($_POST
) 0'dır (NULL
).
Bunun mümkün olduğunu biliyorum (ancak şimdiye kadar herhangi bir jQuery çözümü bulamadım, sadece Prototye kodu (http://webreflection.blogspot.com/2009/03/safari-4-multiple-upload-with-progress.html)).
Bu nispeten yeni gibi görünüyor, bu yüzden lütfen XHR/Ajax ile dosya yüklemenin imkansız olduğundan bahsetmeyin, çünkü kesinlikle çalışıyor.
Safari 5'teki işlevselliğe ihtiyacım var, FF ve Chrome güzel olurdu ama gerekli değil.
Şimdilik kodum şu:
$.ajax({
url: 'php/upload.php',
data: $('#file').attr('files'),
cache: false,
contentType: 'multipart/form-data',
processData: false,
type: 'POST',
success: function(data){
alert(data);
}
});
Safari 5/Firefox 4 ile başlayarak,
FormData
sınıfını kullanmak en kolay yoldur:Artık XMLHttpRequest ile birlikte gönderilmeye hazır bir
FormData
nesneniz var.jQuery'yi sizin için bir
Content-Type
başlığı eklememeye zorlayarakcontentType
seçeneğinifalse
olarak ayarlamanız zorunludur, aksi takdirde sınır dizesi eksik olacaktır. Ayrıca,processData
bayrağını false olarak ayarlı bırakmalısınız, aksi takdirde jQueryFormData
nızı bir dizeye dönüştürmeye çalışacak ve bu da başarısız olacaktır.Şimdi PHP kullanarak dosyayı alabilirsiniz:
(Dosya girişinizde
multiple
özelliğini belirtmediyseniz, yalnızca bir dosya vardır,file-0
, bu durumda sayılar her dosyayla birlikte artacaktır).Eski tarayıcılar için FormData emülasyonu kullanılıyor
Mevcut bir formdan FormData oluşturma
Dosyaları manuel olarak yinelemek yerine, FormData nesnesi mevcut bir form nesnesinin içeriğiyle de oluşturulabilir:
Sayaç yerine PHP'ye özgü bir dizi kullanın
Dosya öğelerinizi aynı şekilde adlandırın ve adı parantez içinde bitirin:
$_FILES['file']` daha sonra yüklenen her dosya için dosya yükleme alanlarını içeren bir dizi olacaktır. Aslında bunu benim ilk çözümüme göre tavsiye ederim çünkü yinelemesi daha kolay.
Sadece Raphael'in harika cevabına bir parça eklemek istedim. Göndermek için JavaScript kullanıp kullanmadığınıza bakılmaksızın PHP'nin aynı `$_FILES'i üretmesini nasıl sağlayacağınız aşağıda açıklanmıştır.
HTML formu:
PHP, JavaScript olmadan gönderildiğinde bu
$_FILES
dosyasını üretir:Dosyaları göndermek için Raphael'in JS'sini kullanarak aşamalı geliştirme yaparsanız...
... PHP'nin
$_FILES
dizisi, göndermek için bu JavaScript kullanıldıktan sonra böyle görünür:Bu güzel bir dizi ve aslında bazı insanlar
$_FILES
i dönüştürüyor, ancak ben göndermek için JavaScript kullanılıp kullanılmadığına bakılmaksızın aynı$_FILES
ile çalışmanın yararlı olduğunu düşünüyorum. İşte JS'de yapılan bazı küçük değişiklikler:(14 Nisan 2017 düzenlemesi: FormData() yapıcısından form öğesini kaldırdım - bu Safari'deki bu kodu düzeltti).
Bu kod iki şey yapar.
input
ad niteliğini otomatik olarak alır. Şimdi,form
putImages sınıfına sahip olduğu sürece, diğer her şey otomatik olarak halledilir. Yani,input
un herhangi bir özel isme sahip olması gerekmez.Bu değişikliklerle, JavaScript ile gönderme artık basit HTML ile gönderme ile tam olarak aynı
$_FILES
dizisini üretir.Bu işlevi okuduğum bazı bilgilere dayanarak oluşturdum.
Bunu
.serialize()
kullanır gibi kullanın, bunun yerine sadece.serializefiles();
koyun.Burada testlerimde çalışıyor.