हम सर्वर पर कई चित्रों को एक साथ अपलोड करने के उदाहरण का उपयोग करके फ़ाइल एपीआई की संभावनाओं पर विचार करेंगे। लेख के अंत में, एक तैयार समाधान एक jQuery प्लगइन के रूप में प्रस्तुत किया गया है।
मैं इसे नहीं पढ़ना चाहता, मैं एक तैयार समाधान में दिलचस्पी रखता हूं।
तो, फ़ाइल एपीआई का उपयोग करने के क्या लाभ हैं:
- बाहरी प्लगइन्स से स्वतंत्रता
- डाउनलोड प्रक्रिया को नियंत्रित करने और इसके बारे में जानकारी प्रदर्शित करने की क्षमता (प्रगति बार हमेशा उपयोगकर्ता को धैर्य जोड़ता है)
- फ़ाइल को पढ़ने और डाउनलोड करने से पहले उसके आकार का पता लगाने की क्षमता (हमारे उदाहरण में, यह हमें उन फ़ाइलों को फ़िल्टर करने की क्षमता देती है जिनमें चित्र नहीं होते हैं और छवियों के थंबनेल दिखाते हैं)
- मानक फ़ाइल चयन फ़ील्ड के माध्यम से एक साथ कई फ़ाइलों का चयन करने की क्षमता
- फ़ाइलों का चयन करने के लिए खींचें और ड्रॉप इंटरफ़ेस का उपयोग करने की क्षमता। हां, हम फ़ाइलों को डेस्कटॉप से सीधे डाउनलोड करने के लिए खींच सकते हैं या छोड़ सकते हैं, उदाहरण के लिए, एक्सप्लोरर से!
कमियों में से, ब्राउज़रों में केवल अपर्याप्त समर्थन ही नोट किया जा सकता है। वर्तमान में, फ़ाइल एपीआई केवल फ़ायरफ़ॉक्स the 3.6 और क्रोम s 6.0 का समर्थन करता है। एक भावना है कि सफारी बहुत जल्द ही ऊपर खींच लेगी, लेकिन आईई और ओपेरा के बारे में कुछ भी स्पष्ट नहीं है (शायद किसी को जानकारी है?)। यह निराशाजनक था, निश्चित रूप से, कि फ़ाइल एपीआई IE9 बीटा का समर्थन नहीं करता है: यह अजीब है, यह देखते हुए कि IE डेवलपर्स अब html 5 के लिए प्रचुर मात्रा में समर्थन की ओर बढ़ रहे हैं। लेकिन जैसा कि यह हो सकता है, यह स्पष्ट है कि भविष्य में सभी ब्राउज़रों को पकड़ना होगा।
एक कामकाजी उदाहरण http://safron.pro/playground/html5uploader/ पर देखा जा सकता है, नीचे केवल सबसे महत्वपूर्ण कोड स्निपेट हैं।
शुरू करने के लिए, हम HTML कोड से निपटेंगे। हमें डिफ़ॉल्ट इनपुट तत्व, फ़ाइलों को खींचने और छोड़ने के लिए एक कंटेनर और उल सूची की आवश्यकता है, जहां हम छवियों के थंबनेल डालेंगे:
<div> <input type="file" name="file" id="file-field" multiple="true" /> </div> <div id="img-container"> <ul id="img-list"></ul> </div>
विशेष कुछ भी नहीं, सिवाय इसके कि इनपुट तत्व के लिए
multiple="true"
विशेषता निर्दिष्ट है। यह आवश्यक है ताकि मानक फ़ाइल चयन संवाद में आप एक ही बार में उनमें से कई का चयन कर सकें। वैसे, फ़ायरफ़ॉक्स 4 के साथ शुरू, ब्राउज़र के डेवलपर्स का वादा है कि कई प्रकार के नफरत करने वाले मानक फ़ाइल चयन फ़ील्ड को छुपाना संभव होगा, और एक छिपे हुए तत्व के लिए क्लिक इवेंट ट्रिगर करके संवाद दिखाएगा।
अब जावास्क्रिप्ट पर चलते हैं (ध्यान दें कि मैंने DOM के हेरफेर को आसान बनाने के लिए jQuery का उपयोग किया था। जो कोई भी किसी कारण से jQuery को छोड़ना चाहता है, वह आसानी से स्क्रिप्ट को इस तरह से संशोधित कर सकेगा जैसे कि इसके बिना करना है)। सबसे पहले, हम उन HTML तत्वों के लिंक को चर में सहेजते हैं जो मुख्य भूमिकाओं में अभिनय करते थे। अगला, हम मानक फ़ाइल चयन फ़ील्ड और उस क्षेत्र के लिए जहां आप फ़ाइलों को खींच और छोड़ सकते हैं, के लिए ईवेंट हैंडलर परिभाषित करते हैं।
// input var fileInput = $('#file-field'); // ul-, var imgList = $('ul#img-list'); // , drag and drop var dropBox = $('#img-container'); // fileInput.bind({ change: function() { displayFiles(this.files); } }); // drag and drop dropBox dropBox.bind({ dragenter: function() { $(this).addClass('highlighted'); return false; }, dragover: function() { return false; }, dragleave: function() { $(this).removeClass('highlighted'); return false; }, drop: function(e) { var dt = e.originalEvent.dataTransfer; displayFiles(dt.files); return false; } });
दोनों ही मामलों में, हैंडलर में हमें फाइललिस्ट ऑब्जेक्ट तक पहुंच मिलती है, जो संक्षेप में फ़ाइल ऑब्जेक्ट्स की एक सरणी है। इस सरणी को डिस्प्लेफाइल्स () फ़ंक्शन में पास किया जाता है, जिसका पाठ नीचे दिया गया है।
function displayFiles(files) { $.each(files, function(i, file) { if (!file.type.match(/image.*/)) { // return true; } // li , progress bar, // file, File ( ) var li = $('<li/>').appendTo(imgList); $('<div/>').text(file.name).appendTo(li); var img = $('<img/>').appendTo(li); $('<div/>').addClass('progress').text('0%').appendTo(li); li.get(0).file = file; // FileReader , // var reader = new FileReader(); reader.onload = (function(aImg) { return function(e) { aImg.attr('src', e.target.result); aImg.attr('width', 150); /* ... ... */ }; })(img); reader.readAsDataURL(file); }); }
फ़ाइल ऑब्जेक्ट में फ़ाइल के बारे में मेटाडेटा है, जैसे कि उसका नाम, आकार और प्रकार (उदाहरण के लिए, उदाहरण के लिए, छवि / gif), क्रमशः, नाम, आकार और प्रकार गुणों में। फ़ाइल की सामग्री तक पहुँचने के लिए, एक विशेष FileReader ऑब्जेक्ट है।
DisplayFiles () फ़ंक्शन के अंदर, हम फ़ाइलों की स्थानांतरित सरणी से गुजरते हैं और पहले उन छवियों को बाहर निकालते हैं जो चित्र नहीं हैं। इसके बाद, प्रत्येक छवि के लिए, ली सूची का एक तत्व बनाया जाता है, जहां img तत्व को रखा जाने तक खाली होता है (ध्यान दें कि फ़ाइल ली संपत्ति भी प्रत्येक एल एल तत्व में संबंधित वस्तु से बनाई गई है)। उसके बाद, FileReader का एक उदाहरण बनाया गया है और इसके लिए ऑनलोड हैंडलर को परिभाषित किया गया है, जिसमें पहले बनाए गए img तत्व के src विशेषता में डेटा को सीधे स्थानांतरित किया जाता है। FileReader ऑब्जेक्ट का readAsDataURL () विधि एक फ़ाइल ऑब्जेक्ट को एक पैरामीटर के रूप में लेता है और इससे डेटा पढ़ना शुरू करता है। परिणामस्वरूप, मानक फ़ील्ड के माध्यम से चयनित या ब्राउज़र पर सीधे खींचे गए सभी चित्रों के लिए, हम उनके थंबनेल (कृत्रिम रूप से 150 मिलियन तक कम) देखते हैं।
और क्या करना बाकी है? यह केवल सर्वर पर सभी चयनित फ़ाइलों के बहुत डाउनलोड को लागू करने के लिए बनी हुई है। ऐसा करने के लिए, कुछ बटन या लिंक बनाएं, जब आप उस पर क्लिक करते हैं, तो आपको बस सभी बनाए गए झूठे तत्वों से गुजरना होगा, उनकी फ़ाइल संपत्ति को पढ़ना होगा और इसे अपलोडफिल () फ़ंक्शन में भेजना होगा, जिसका पाठ नीचे दिया गया है। मैं ध्यान देता हूं कि सरलीकरण के लिए, मैंने एक फ़ंक्शन के माध्यम से लोडिंग को लागू किया, और एक वास्तविक उदाहरण में, http://safron.pro/playground/html5uploader/ पर स्थित, मैंने एक अपलोडरऑबजेक्ट में सभी लोडिंग कार्यों को एकत्र किया, जिसके निर्माण के दौरान आप अतिरिक्त पैरामीटर पास कर सकते हैं जैसे कि कॉलबैक लोडिंग प्रक्रिया के बारे में जानकारी प्राप्त करने के लिए कार्य करता है।
function uploadFile(file, url) { var reader = new FileReader(); reader.onload = function() { var xhr = new XMLHttpRequest(); xhr.upload.addEventListener("progress", function(e) { if (e.lengthComputable) { var progress = (e.loaded * 100) / e.total; /* ... ... */ } }, false); /* ... load error xhr.upload ... */ xhr.onreadystatechange = function () { if (this.readyState == 4) { if(this.status == 200) { /* ... ! this.responseText ... */ } else { /* ... ! ... */ } } }; xhr.open("POST", url); var boundary = "xxxxxxxxx"; // xhr.setRequestHeader("Content-Type", "multipart/form-data, boundary="+boundary); xhr.setRequestHeader("Cache-Control", "no-cache"); // var body = "--" + boundary + "\r\n"; body += "Content-Disposition: form-data; name='myFile'; filename='" + file.name + "'\r\n"; body += "Content-Type: application/octet-stream\r\n\r\n"; body += reader.result + "\r\n"; body += "--" + boundary + "--"; if(xhr.sendAsBinary) { // firefox xhr.sendAsBinary(body); } else { // chrome ( W3C) xhr.send(body); } }; // reader.readAsBinaryString(file); }
यह पहले से ही परिचित FileReader ऑब्जेक्ट का एक उदाहरण बनाता है, उसी तरह जैसे ऊपर; इसे एक ऑनलोड ईवेंट हैंडलर सौंपा गया है, जिसमें XMLHttpRequest बनाया गया है (दुर्भाग्य से, आप अभी तक jQuery के अजाक्स इंटरफ़ेस का उपयोग नहीं कर सकते, क्योंकि फाइल अभी तक इसके लिए प्रदान नहीं की गई हैं)। दूसरे संस्करण के XMLHttpRequest में, अपलोड संपत्ति दिखाई दी है, जिसमें एक लोडर ऑब्जेक्ट है जो प्रगति, लोड और त्रुटि घटनाओं को संभाल सकता है (अधिक विवरण के लिए http://www.w3.org/TR/XMLHttpRequest2-#xmlhttprequesteventtarget ) देखें। ऊपर दिया गया उदाहरण केवल प्रगति घटना के प्रसंस्करण को दर्शाता है। अगला, हम अनुरोध पूरा करने वाले हैंडलर को स्वयं अनुरोध करते हैं (लोडर ऑब्जेक्ट की घटनाओं के विपरीत, यह पहले से ही कहा जाता है जब सभी डेटा डाउनलोड किया गया है और सर्वर से प्रतिक्रिया मिली है), हम दो अतिरिक्त हेडर जोड़ते हैं और अनुरोध बॉडी बनाते हैं, फाइलरैडर ऑब्जेक्ट की परिणाम संपत्ति से डेटा पढ़ते हैं। उसके बाद, डाउनलोड शुरू होता है। मैं केवल इस बात पर ध्यान देता हूं कि वर्तमान W3C विनिर्देश के अनुसार, यह समझा जाता है कि XMLHttpRequest ऑब्जेक्ट की सेंड () विधि द्विआधारी डेटा को पैरामीटर में स्वीकार कर सकती है, जिसे Google Chrome में सफलतापूर्वक लागू किया जाता है, हालाँकि, फ़ायरफ़ॉक्स में यह एक विशेष SendAsBinary () विधि के माध्यम से अपने तरीके से किया जाता है। इसलिए, भेजने से पहले, हम जाँचते हैं कि क्या SendAsBinary () विधि अनुरोध ऑब्जेक्ट में परिभाषित की गई है, और यदि हां, तो इसका उपयोग करें।
वह, वास्तव में, सब है। हम HTML 5 के अनुमोदन और वितरण के लिए तत्पर हैं!
कुछ लिंक
- http://safron.pro/playground/html5uploader/ - ऊपर वर्णित (जो कुछ और था) का एक कार्यशील उदाहरण
- http://safron.pro/playground/html5uploader/full.zip - संपूर्ण कोड संग्रह में है
- http://html5test.com - html 5 के अनुपालन के लिए ब्राउज़रों की जाँच (बहुत दृश्य)
- http://playground.html5rocks.com - Google के कोड के साथ प्रयोग करने के लिए एक मंच (इसका इंटरफ़ेस उन लोगों से परिचित होगा जिन्होंने कई अलग-अलग एपीआई का उपयोग किया था)
युपीडी
उपरोक्त सभी के उपयोग को सरल बनाने के लिए, एक jQuery प्लगइन बनाया गया था। इसके साथ, आप जहाँ संभव हो, फ़ाइल एपीआई के माध्यम से फाइल अपलोड कर सकते हैं और प्रतिस्थापन को लागू कर सकते हैं (उदाहरण के लिए, सामान्य फॉर्म सबमिशन) जहां नहीं। श्रमिकों के अनुरोध पर और टिप्पणीकारों की टिप्पणियों के अनुसार, ब्राउज़र में फॉर्मडाटा ऑब्जेक्ट के माध्यम से एक डाउनलोड जोड़ा गया था जो इसका समर्थन करता है (क्रोम, सफारी 5+, एफएफ 4+)। प्लगइन फ़ाइल के शीर्ष पर मापदंडों, विधियों, साथ ही उपयोग के संक्षिप्त उदाहरणों का विवरण है। उपयोग का एक और पूरा उदाहरण यहां देखा जा सकता है (यह इस लेख से प्रारंभिक उदाहरण है, केवल प्लगइन के उपयोग के लिए फिर से बनाया गया है, इसका पूर्ण कोड, सर्वर साइड सहित,
सूत्रों का उपयोग किया
- https://developer.mozilla.org/en/using_files_from_web_applications - मोज़िला डेवलपर्स वेबसाइट पर फ़ाइल इंटरफ़ेस के बारे में लेख
- https://developer.mozilla.org/En/XMLHttpRequest/Using_XMLHttpRequest - XMLHttpRequest का एक ही स्थान पर उपयोग करने के बारे में लेख
- http://www.w3.org/TR/FileAPI/ - W3C वेबसाइट पर फ़ाइल एपीआई का वर्तमान विनिर्देश
- http://www.w3.org/TR/XMLHttpRequest2/ - वर्तमान XMLHttpRequest विनिर्देशन एक ही स्थान पर
UPD2
Glebovgin उपयोगकर्ता के अनुरोध पर , प्लगइन को संशोधित किया गया था ताकि न केवल फ़ाइल ऑब्जेक्ट को सीधे भेजा जा सके, बल्कि बूँद डेटा (ब्लॉब ऑब्जेक्ट) भी संभव हो सके। यह उपयोगी हो सकता है अगर सर्वर पर भेजने की आवश्यकता है, उदाहरण के लिए, कैनवास की सामग्री, अच्छी तरह से, या बस मैन्युअल रूप से उत्पन्न डेटा।
डेमो में (जो थोड़ा अलग पते पर चला गया ), कैनवास से एक तस्वीर भेजने का एक उदाहरण जोड़ा गया था। फिलहाल यह फीचर एफएफ, क्रोम, आईई 10 में काम करता है।
स्रोत कोड अब GitHub पर उपलब्ध है । टिप्पणियाँ, सुझाव, सुधार का स्वागत है!