Soru Dosyaları eşzamansız olarak nasıl yükleyebilirim?


JQuery ile eşzamansız olarak bir dosya yüklemek istiyorum. Bu benim HTML'm:

<span>File</span>
<input type="file" id="file" name="file" size="10"/>
<input id="uploadbutton" type="button" value="Upload"/>

Ve işte benim Jquery kod:

$(document).ready(function () {
    $("#uploadbutton").click(function () {
        var filename = $("#file").val();

        $.ajax({
            type: "POST",
            url: "addFile.do",
            enctype: 'multipart/form-data',
            data: {
                file: filename
            },
            success: function () {
                alert("Data Uploaded: ");
            }
        });
    });
});

Yüklenen dosya yerine, yalnızca dosya ismini alıyorum. Bu sorunu çözmek için ne yapabilirim?

Mevcut çözüm

Kullanıyorum jQuery Form Eklentisi dosya yüklemek için


2609
2017-10-03 10:22


Menşei


Sadece dosya ismini alıyorsunuz çünkü var dosya adınız $ ('# file') değerini alıyor, girişte yer alan dosya değil - Jimmy
İşte iyi bir tane: http://blueimp.github.io/jQuery-File-Upload/ - HTML5 ajax yükleme - Desteklenmeyen tarayıcılar için iframe'ler için zarif geri dönüş - Çok dosyalı async upload Kullantık ve harika çalışıyor. (Dokümantasyon burada) - Ashish Panery
jQuery Form Plugin, kullanımı en basit ve çapraz tarayıcı uyumlu bir şekilde görünüyor ... doğru muyum? - Lyth
Ayrıca şunu da kontrol edin: stackoverflow.com/questions/6974684/...Burada jQuery ile nasıl başarılacağını açıklıyor - Chococroc
@Jimmy Bunun yerine girişte yer alan dosyayı nasıl alır? - alex


Cevaplar:


İle HTML5 Ajax ve jQuery ile dosya yükleme yapabilirsiniz. Sadece bu değil, dosya doğrulamalarını (ad, boyut ve MIME türü) yapabilir veya ilerleme olayını HTML5 ilerleme etiketi (veya bir div) ile yapabilirsiniz. Son zamanlarda bir dosya yükleyici yapmak zorunda kaldım, ancak kullanmak istemedim flaş Iframe'ler veya eklentiler ve bazı araştırmalardan sonra çözümle geldim.

HTML:

<form enctype="multipart/form-data">
    <input name="file" type="file" />
    <input type="button" value="Upload" />
</form>
<progress></progress>

Öncelikle, isterseniz, bazı doğrulama yapabilirsiniz. Örneğin, dosyanın onChange olayında:

$(':file').on('change', function() {
    var file = this.files[0];
    if (file.size > 1024) {
        alert('max upload size is 1k')
    }

    // Also see .name, .type
});

Şimdi Ajax, düğmenin tıklaması ile birlikte gönderilir:

$(':button').on('click', function() {
    $.ajax({
        // Your server script to process the upload
        url: 'upload.php',
        type: 'POST',

        // Form data
        data: new FormData($('form')[0]),

        // Tell jQuery not to process data or worry about content-type
        // You *must* include these options!
        cache: false,
        contentType: false,
        processData: false,

        // Custom XMLHttpRequest
        xhr: function() {
            var myXhr = $.ajaxSettings.xhr();
            if (myXhr.upload) {
                // For handling the progress of the upload
                myXhr.upload.addEventListener('progress', function(e) {
                    if (e.lengthComputable) {
                        $('progress').attr({
                            value: e.loaded,
                            max: e.total,
                        });
                    }
                } , false);
            }
            return myXhr;
        }
    });
});

Gördüğünüz gibi, HTML5 (ve bazı araştırmalar) dosya yükleme ile sadece mümkün değil, aynı zamanda süper kolay. İle deneyin Google Chrome Örneklerin bazı HTML5 bileşenleri her tarayıcıda mevcut değildir.


2336
2018-01-06 13:34



Daha sonra upload.php dosyasında $ _FILES kullanabilir miyim? - Alessandro Cosentino
Bu, Internet Explorer'da ancak yalnızca Sürüm 10'da çalışmalıdır.caniuse.com/xhr2) - Samir
IE7-9'da çalışmıyor - KevinDeus
Merhaba, PHP'nin tercih ettiğiniz dil olduğunu takdir ediyorum ... ama bunun ASP.NET MVC'de de çalışıp çalışmadığını bilmek ister misiniz? Ben bir .NET geliştiricisi ve bazı AJAX dosya yükleme yapmak için basit bir örnek kullanmaya çalıştım ama sunucu tarafı AJAX aracılığıyla gönderdiğim dosyayı almıyorum. En yeni Chrome'u kullanıyorum. - Shumii
Onun Form verisi Burada tüm sihri kim yapar? Bu dokümanları kontrol ettiğinizden emin olun. Birden çok dosya ve alanla ilgili tüm sorularınızı kapsar. - incarnate


JQuery için dosya yükleme yaparken çeşitli hazır eklentileri vardır.

Bu tür bir gönderiyi yapmak harikulade bir deneyim değildir, bu yüzden insanlar hazır çözümler kullanmaktan zevk alırlar.

İşte birkaç tane:

NPM hakkında daha fazla proje (anahtar kelime olarak "jquery-plugin" kullanarak) veya Github'da arama yapabilirsiniz.


335
2017-10-15 10:35



AjaxFUP-link bozuk görünüyor. Şunlara başvurduğundan şüpheleniyorum: valums.com/ajax-upload - UlfR
Başka bir okuma eklentisi için her zaman Filepicker.io, Bu tür kötü büyük dosya desteği sorunları ile ilgilenen bir tür güzel. - brettcvz
Aslında sadece yaklaşık 10 satır vanilyalı JS. Gerçekten çok kötü değil. - mpen
Hazır çözüm eklentileri işe yarayabilir, ancak bir süre sonra işe yaramadığını ve işe yaramaz betiklerle hacklemeniz gerektiğini düşündüğünüzde işe yaramaz. Yani, her iki yol da gider. - fletchsod
Kullanabilirmiyim JQuery File Uploader birden fazla video için ..? destekleyecek mi ..? - Mr world wide


2017 Güncellemesi: Yine de tarayıcılara bağlı sizin demografik kullanımlar.

"Yeni" HTML5 ile anlaşılması gereken önemli bir şey file API öyle IE 10'a kadar desteklenmedi. Hedeflediğiniz belirli pazarın, eski Windows sürümlerine göre ortalamanın üzerinde bir ön yoğunluğu varsa, buna erişiminiz olmayabilir.

2017'ye girerken, tarayıcıların yaklaşık% 5'i IE 6, 7, 8 veya 9'dan bir tanesidir. Büyük bir şirkete girerseniz (örneğin bu bir B2B aracı veya eğitim için verdiğiniz bir şey) bu sayı roket olabilir. Sadece birkaç ay önce - 2016'da, makinelerinin% 60'ından fazlası ile IE8 kullanan bir şirkette çalıştım.

Yani bir şey yapmadan önce: tarayıcıyı kontrol et sizin kullanıcılar kullan. Eğer yapmazsanız, "benim için çalışır" ın neden bir müşteriye teslim edilebilirlikte yeterince iyi olmadığı konusunda hızlı ve acı veren bir ders öğreneceksiniz.

Benim cevabım 2008'den geliyor.


Ancak, geçerli olmayan JS dosya yükleme yöntemleri vardır. Sayfada (CSS ile gizlediğiniz) bir iframe oluşturabilir ve ardından bu iframe'e göndermek için formunuzu hedefleyebilirsiniz. Ana sayfa taşınmaya ihtiyaç duymaz.

Bu "gerçek" bir gönderi yani tamamen etkileşimli değil. Eğer statüye ihtiyacınız varsa, bunu işlemek için sunucu tarafına ihtiyacınız var. Bu, sunucunuza bağlı olarak büyük ölçüde değişir. ASP.NET daha güzel mekanizmalara sahiptir. PHP düz başarısız, ama kullanabilirsiniz Perl veya etrafında almak için Apache modifikasyonları.

Birden fazla dosya yüklemesine ihtiyacınız varsa, her dosyayı tek tek yapmak en iyisidir (maksimum dosya yükleme sınırlarının üstesinden gelmek için). İframe'e ilk formu gönderin, yukarıdakileri kullanarak ilerlemesini izleyin ve bittiğinde, iframe'e ikinci formu gönderin, vb.

Ya da bir Java / Flash çözümü kullanın. Gönderileriyle neler yapabilecekleri konusunda çok daha esnekler.


237
2017-10-03 10:41



Kayıt için tarayıcı Dosya API'sini destekliyorsa artık saf AJAX dosya yüklemeleri yapmak mümkün - developer.mozilla.org/en/using_files_from_web_applications - meleyal
IE9 desteğine ihtiyacınız olmadıkça. caniuse.com/fileapi - Oli
iframe çözümü oldukça basit ve çalışmak kolay - Matthew Lock
Bu oldukça eski bir cevaptır, ancak biraz yanıltıcıdır .. IE, XHR'yi yerel olarak IE7 kadar destekledi ve ActiveX aracılığıyla IE5'e kadar destekledi. w3schools.com/ajax/ajax_xmlhttprequest_create.asp. Bunu yapmanın pratik yolu kesinlikle flaş (şok dalgası) bileşenlerini hedeflemek ya da bir Flash / ActiveX (Silverlight) denetimini yuvarlamaktı. Bir istek gelip javascript ile yanıtı ele alabiliyorsanız, ajax .., ajax'ın xhr ile eşanlamlı olduğunu söylese de, kendisi yükün teslimini / değişimini sağlayan alt çizgi mekanizmasını / bileşenlerini tarif etmez. - Brett Caswell
@BrettCaswell AJAX / XHR'nin mümkün olmadığından bahsetmiyordum, sadece IE'nin eski - ama hiç bitmeyen sürümlerinde onlarla bir dosya yayınlamak mümkün değildi. Bu tamamen doğruydu ve kaldı. - Oli


Kullanmanı öneririm İnce Yükleyici bu amaç için eklenti. Sizin JavaScript kod şöyle olurdu:

$(document).ready(function() {
  $("#uploadbutton").jsupload({
    action: "addFile.do",
    onComplete: function(response){
      alert( "server response: " + response);
    }
  });
});

105
2017-11-21 16:38



JSON kullanır - PHP eski sürümü için mümkün olmayan kullanım olacaktır. - Lorenzo Manucci
Ajax Dosya Yükleme'den çok daha temiz görünüyor, sadece lanet şeyi kullanmak için çok büyük bir kod parçası eklemem gerekiyor. - ripper234
URL şimdi valums.com/ajax-upload. - Patrick Fisher
"Bu eklenti GNU GPL 2 veya üstü ve GNU LGPL 2 veya daha üstü sürümlerde açık." Kopyayı veya değiştirilmiş bir sürümü dağıtmadığınız sürece, projenizi açmanız gerekmez. - Trantor Liu
Bu web sitesidir (fineuploader.com) Şimdi buldum , V4.2. - Andrew_1510


Not: Bu cevap güncel değil, artık XHR kullanarak dosya yüklemek mümkün.


Kullanarak dosya yükleyemezsiniz XMLHttpRequest (Ajax). Bir iframe veya Flash kullanarak efekti simüle edebilirsiniz. Mükemmel jQuery Form Eklentisi Efekt almak için dosyalarınızı iframe yoluyla gönderir.


87
2017-10-03 10:36



Evet, iframe gönderebilir ve dosyayı buradan yakalayabilirsiniz. Bununla ilgili çok sınırlı deneyime sahibim, bu yüzden üzerine yorum yapamam. - Mattias
Küçük bir açıklama: krom ve firefox'un en son sürümlerinde mümkündür, stackoverflow.com/questions/4856917/... - Alleo


Bu AJAX dosya yükleme jQuery eklentisi dosyayı somehwere yükler ve Bir geri dönüşe cevap, başka bir şey değil.

  • Belirli bir HTML'ye bağlı değildir, sadece bir ver <input type="file">
  • Sunucunuzun herhangi bir şekilde yanıt vermesini gerektirmez
  • Ne kadar dosya kullandığınız ya da sayfada nerede olduğu önemli değil

- En az kadar kullan -

$('#one-specific-file').ajaxfileupload({
  'action': '/upload.php'
});

- ya da - kadar

$('input[type="file"]').ajaxfileupload({
  'action': '/upload.php',
  'params': {
    'extra': 'info'
  },
  'onComplete': function(response) {
    console.log('custom handler for file:');
    alert(JSON.stringify(response));
  },
  'onStart': function() {
    if(weWantedTo) return false; // cancels upload
  },
  'onCancel': function() {
    console.log('no file selected');
  }
});

81
2017-07-29 00:34



1.9.1 ile çalışmıyor: | - user840250
@ user840250 jQuery 1.9.1? - Jordan Feldstein


Gelecek okuyucular için sarılıyoruz.

Eşzamansız Dosya Yükleme

HTML5 ile

Dosya yükleyebilirsin jQuery ile kullanmak $.ajax() eğer metot Form verisi ve Dosya API'sı desteklenir (her ikisi de HTML5 özellikleri).

Ayrıca dosya gönderebilirsiniz FormData olmadan Ancak Dosya API'sı, dosyalarının gönderilebilecekleri şekilde işlenmesi için mevcut olmalıdır. XMLHttpRequest (Ajax).

$.ajax({
  url: 'file/destination.html', 
  type: 'POST',
  data: new FormData($('#formWithFiles')[0]), // The form with the file inputs.
  processData: false,
  contentType: false                    // Using FormData, no need to process data.
}).done(function(){
  console.log("Success: Files sent!");
}).fail(function(){
  console.log("An error occurred, the files couldn't be sent!");
});

Hızlı, saf bir JavaScript için (jQuery yok) örnek "FormData nesnesini kullanarak dosya gönderme".

Geri çekil

HTML5 desteklenmediğinde (hayır Dosya API'sı) sadece diğer saf JavaScript çözümü (hayır flaş veya herhangi bir başka tarayıcı eklentisi) gizli iframe kullanılmadan asenkronize bir isteği taklit etmeye izin veren teknik XMLHttpRequest nesne.

Dosya girişleriyle formun hedefi olarak bir iframe ayarlamaktan oluşur. Kullanıcı bir istek gönderdiğinde ve dosyalar yüklendiğinde, ana sayfayı yeniden oluşturmak yerine iframe içinde yanıt görüntülenir. İframe'i gizlemek, tüm süreci kullanıcıya şeffaf hale getirir ve asenkron istekleri öykünür.

Doğru şekilde yapılırsa, hemen hemen herhangi bir tarayıcıda çalışmalıdır, ancak iframe'den yanıtın nasıl alınacağı konusunda bazı uyarılar vardır.

Bu durumda, gibi bir sarmalayıcı eklentisi kullanmayı tercih edebilirsiniz Bifröst hangi kullanır iframe tekniği ama aynı zamanda bir jQuery Ajax taşımacılığı izin vermek dosyaları gönder sadece ile $.ajax() böyle bir yöntem:

$.ajax({
  url: 'file/destination.html', 
  type: 'POST',
  // Set the transport to use (iframe means to use Bifröst)
  // and the expected data type (json in this case).
  dataType: 'iframe json',                                
  fileInputs: $('input[type="file"]'),  // The file inputs containing the files to send.
  data: { msg: 'Some extra data you might need.'}
}).done(function(){
  console.log("Success: Files sent!");
}).fail(function(){
  console.log("An error occurred, the files couldn't be sent!");
});

eklentiler

Bifröst jQuery'nin ajax yöntemine geri dönüş desteği ekleyen küçük bir sarıcıdır, ancak yukarıda bahsedilen eklentilerden birçoğu jQuery Form Eklentisiveya jQuery Dosya Yükleme HTML5'ten tüm desteyi farklı geri dönüşlere ve işlemi kolaylaştırmak için bazı yararlı özelliklere dahil edin. İhtiyaçlarınıza ve gereksinimlerinize bağlı olarak, çıplak bir uygulamayı veya bu eklentilerden birini düşünmek isteyebilirsiniz.


75
2017-08-25 14:17



Belgelere dayanarak dikkat etmeniz gereken bir şey de göndermelisiniz. contentType: false. Bunu chrome ile göndermediğimde, form içeriği türü jQuery tarafından geçersiz hale getirildi. - ash
Güzel cevap. İyileştirme için birkaç öneri: Örneğin, cevabın ilgisi olmayan bölümlerini çıkarın. .done() ve .fail() geri aramaları. Ayrıca, kullanmadan bir örnek FormData ve pro / cons bir listesi harika olurdu. - Zero3
Bu hatayı aldım: TypeError: Argument 1 of FormData.constructor does not implement interface HTMLFormElement. - candlejack


İyi çalışacak görüntüleri yüklemek için aşağıdaki senaryoyu kullanıyorum.

HTML

<input id="file" type="file" name="file"/>
<div id="response"></div>

JavaScript

jQuery('document').ready(function(){
    var input = document.getElementById("file");
    var formdata = false;
    if (window.FormData) {
        formdata = new FormData();
    }
    input.addEventListener("change", function (evt) {
        var i = 0, len = this.files.length, img, reader, file;

        for ( ; i < len; i++ ) {
            file = this.files[i];

            if (!!file.type.match(/image.*/)) {
                if ( window.FileReader ) {
                    reader = new FileReader();
                    reader.onloadend = function (e) {
                        //showUploadedItem(e.target.result, file.fileName);
                    };
                    reader.readAsDataURL(file);
                }

                if (formdata) {
                    formdata.append("image", file);
                    formdata.append("extra",'extra-data');
                }

                if (formdata) {
                    jQuery('div#response').html('<br /><img src="ajax-loader.gif"/>');

                    jQuery.ajax({
                        url: "upload.php",
                        type: "POST",
                        data: formdata,
                        processData: false,
                        contentType: false,
                        success: function (res) {
                         jQuery('div#response').html("Successfully uploaded");
                        }
                    });
                }
            }
            else
            {
                alert('Not a vaild image!');
            }
        }

    }, false);
});

açıklama

Cevap kullanıyorum div yüklendikten sonra yükleme animasyonu ve yanıtı göstermek için.

En iyi bölüm, bu betiği kullandığınızda ids & etc gibi ek verileri dosyaya gönderebilirsiniz. Bahsettim extra-data komut dosyasında olduğu gibi.

PHP düzeyinde bu normal dosya yükleme olarak çalışacaktır. ekstra veri olarak alınabilir $_POST veri.

Burada bir eklenti ve malzeme kullanmıyorsunuz. Kodu istediğiniz gibi değiştirebilirsiniz. Burada körü körüne kodlama yapmıyorsunuz. Bu herhangi bir jQuery dosya yükleme temel işlevidir. Aslında Javascript.


57
2018-01-25 11:03



JQuery'yi kullanmak ve seçim motoru ve olay işleyicilerini kullanmamak için -1. addEventListener tarayıcılar arası değildir. - Mark
Çünkü sadece birkaç değişiklikle, çoğunlukla buna dayalı olan ayrı bir cevap eklemek anlamsız olacaktır. Bunun yerine, bu cevap düzeltilmelidir. - Mark
@RainFromHeaven, lütfen, cevabı düzenleyebilir misiniz? Bunu tarayıcılar arası şekilde nasıl yapacağımı bilmiyorum. - Thiago Negri
Hala IE 9 ve aşağı çalışmıyor. Allot kullanıcıları hala IE'nin bu sürümlerini kullanır. - Pierre
Birisi bunun asp.net'de nasıl çalışılabileceğini açıklayabilir mi? Webmethod kullanıyor muyum? Varsa neye benziyordu? - Arbaaz