2012-12-01 26 views
24

के माध्यम से एक के बाद एक अपलोड मैं एक से अधिक फ़ाइलों प्रपत्र अपलोड किया है:एचटीएमएल 5 कई फाइल अपलोड: AJAX

<input type="file" name="files" multiple /> 

मैं ajax के साथ इन फ़ाइलों पोस्टिंग कर रहा हूँ। मैं चयनित फ़ाइलों को एक-एक करके अपलोड करना चाहता हूं (व्यक्तिगत प्रगति सलाखों को बनाने के लिए, और जिज्ञासा से बाहर)।

मैं द्वारा

FL = form.find('[type="file"]')[0].files 
F = form.find('[type="file"]')[0].files[0] 

yieling

FileList { 0=File, 1=File, length=2 } 
File { size=177676, type="image/jpeg", name="img.jpg", more...} 

फाइल या व्यक्तिगत फ़ाइलों की सूची प्राप्त कर सकते हैं लेकिन FileList अपरिवर्तनीय है और मैं समझ नहीं कैसे एक फ़ाइल प्रस्तुत करने के लिए।

मुझे लगता है कि यह संभव है क्योंकि मैंने http://blueimp.github.com/jQuery-File-Upload/ देखा था। मैं इस प्लगइन का उपयोग नहीं करना चाहता हूं, हालांकि यह परिणाम के रूप में सीखने के बारे में ज्यादा है (और इसे वैसे भी बहुत अधिक कस्टमाइज़ करना होगा)। मैं फ्लैश का उपयोग भी नहीं करना चाहता हूं।

उत्तर

26

यह एक सिंक्रोनस ऑपरेशन होने के लिए, आपको अंतिम स्थानांतरण होने पर नया स्थानांतरण शुरू करने की आवश्यकता है। जीमेल, उदाहरण के लिए, एक साथ, सबकुछ एक साथ भेजें। कच्चे XmlHttpRequest उदाहरण पर AJAX फ़ाइल अपलोड पर प्रगति की घटना progress या onprogress है।

तो, प्रत्येक $.ajax() के बाद, सर्वर पक्ष पर (जो मुझे नहीं पता कि आप क्या उपयोग करेंगे), अगले इनपुट पर AJAX निष्पादित करने के लिए JSON प्रतिक्रिया भेजें। चीजों को आसान बनाने के लिए एक विकल्प AJAX तत्व को प्रत्येक तत्व में बांधना होगा, ताकि आप success$(this).sibling('input').execute_ajax() में बस ऐसा कर सकें।

कुछ इस तरह:

$('input[type="file"]').on('ajax', function(){ 
    var $this = $(this); 
    $.ajax({ 
    'type':'POST', 
    'data': (new FormData()).append('file', this.files[0]), 
    'contentType': false, 
    'processData': false, 
    'xhr': function() { 
     var xhr = $.ajaxSettings.xhr(); 
     if(xhr.upload){ 
     xhr.upload.addEventListener('progress', progressbar, false); 
     } 
     return xhr; 
    }, 
    'success': function(){ 
     $this.siblings('input[type="file"]:eq(0)').trigger('ajax'); 
     $this.remove(); // remove the field so the next call won't resend the same field 
    } 
    }); 
}).trigger('ajax'); // Execute only the first input[multiple] AJAX, we aren't using $.each 

ऊपर कोड को कई <input type="file"> के लिए होगा, लेकिन नहीं <input type="file" multiple> के लिए, उस स्थिति में, यह होना चाहिए:

var count = 0; 

$('input[type="file"]').on('ajax', function(){ 
    var $this = $(this); 
    if (typeof this.files[count] === 'undefined') { return false; } 

    $.ajax({ 
    'type':'POST', 
    'data': (new FormData()).append('file', this.files[count]), 
    'contentType': false, 
    'processData': false, 
    'xhr': function() { 
     var xhr = $.ajaxSettings.xhr(); 
     if(xhr.upload){ 
     xhr.upload.addEventListener('progress', progressbar, false); 
     } 
     return xhr; 
    }, 
    'success': function(){ 
     count++; 
     $this.trigger('ajax'); 
    } 
    }); 
}).trigger('ajax'); // Execute only the first input[multiple] AJAX, we aren't using $.each 
+4

ध्यान दें कि यह कोड है कि FormData और XMLHttpRequest2 केवल, पुराने ब्राउज़र – pocesar

+4

के लिए कोई हैक्स सोच रहा था क्यों यह इतना स्वादिष्ट लग रहा है ... समर्थन वास्तव में आधुनिक ब्राउज़रों के लिए है;) – Selosindis

+5

एक नए 'फार्म' बनाना और जोड़ने '(नया फॉर्मडाटा()) का उपयोग करके एक-एक करके फ़ाइलें। (' फ़ाइल ', this.files [count])' मैं जो खोज रहा था, धन्यवाद! – Mark

7

This looks like a very good tutorial, just what you're looking for

यह नोट किया गया है कि वेनिला AJAX के माध्यम से अपलोड करना सभी ब्राउज़रों में समर्थित नहीं है, और मैं अभी भी iframe का उपयोग करने की अनुशंसा करता हूं। (आईई गतिशील रूप से एक आईफ्रेम बनाते हैं और इसे जावास्क्रिप्ट का उपयोग करके पोस्ट करते हैं)

I have always been using this script और मुझे यह बहुत संक्षिप्त लगता है। अगर आप एक आईफ्रेम बनाने के माध्यम से अपलोड करना सीखना चाहते हैं, तो आपको इसके स्रोत के माध्यम से खोदना चाहिए।

आशा है कि यह मदद करता है :)

अतिरिक्त संपादित आइफ्रेम विधि के साथ

बनाने के लिए प्रगति सलाखों, आप कुछ काम सर्वर साइड करने की आवश्यकता होगी। आप php का उपयोग कर रहे हैं, तो आप उपयोग कर सकते हैं:

  • php5.4 +
  • Upload progress package php < 5 के लिए के लिए Session upload progress।प्रत्येक अपलोड किया है एक यूआईडी, आप 'प्रगति' पर है कि आईडी के साथ संबद्ध के लिए अनुरोध करेंगे - उपयोग nginx आप भी साथ अपने Upload progress module

    ये सब काम करते हैं उसी तरह संकलित करने के लिए चुन सकते हैं 4

हैं AJAX के माध्यम से लगातार अंतराल। यह सर्वर द्वारा निर्धारित अपलोड प्रगति को वापस कर देगा।

+0

के लिए jQuery दस्तावेज़ों का संदर्भ लें, पहला लिंक वास्तव में फॉर्मडाटा ऑब्जेक्ट्स के बारे में एक अच्छा ट्यूटोरियल था, धन्यवाद! – Mark

1

मुझे एक ही समस्या का सामना करना पड़ रहा था और इस समाधान के साथ आया था। मैं बस मल्टीपार्ट के साथ फॉर्म पुनर्प्राप्त करता हूं, और रिकर्सिव कॉल (फ़ाइल के बाद फ़ाइल) में AJAX अनुरोध शुरू करता है, जो केवल पूरा होने पर ही कॉल करता है।

var form = document.getElementById("uploadForm"); 
var fileSelect = document.getElementById("photos"); 
var uploadDiv = document.getElementById("uploads"); 

form.onsubmit = function(event) { 
    event.preventDefault(); 

    var files = fileSelect.files; 
    handleFile(files, 0); 
}; 

function handleFile(files, index) { 
    if(files.length > index) { 
     var formData = new FormData(); 
     var request = new XMLHttpRequest(); 

     formData.append('photo', files[ index ]); 
     formData.append('serial', index); 
     formData.append('upload_submit', true); 

     request.open('POST', 'scripts/upload_script.php', true); 
     request.onload = function() { 
      if (request.status === 200) { 
       console.log("Uploaded"); 
       uploadDiv.innerHTML += files[ index ].name + "<br>"; 
       handleFile(files, ++index); 
      } else { 
       console.log("Error"); 
      } 
     }; 
     request.send(formData); 
    } 
} 
+0

यह नहीं पूछा गया था। ओपी ने चयनित प्रगति सलाखों के साथ चयनित फाइलों को एक-एक करके अपलोड करने के लिए कहा। Downvoted। – TheCarver

संबंधित मुद्दे