वेब की सबसे ज़्यादा इस्तेमाल की जाने वाली सुविधाओं में से एक, उपयोगकर्ता के स्थानीय डिवाइस पर मौजूद फ़ाइलों को चुनना और उनके साथ इंटरैक्ट करना है. इससे उपयोगकर्ताओं को फ़ाइलें चुनने और उन्हें किसी सर्वर पर अपलोड करने की अनुमति मिलती है. उदाहरण के लिए, फ़ोटो शेयर करते समय या टैक्स से जुड़े दस्तावेज़ सबमिट करते समय. इससे साइटों को नेटवर्क पर डेटा ट्रांसफ़र किए बिना, फ़ाइलों को पढ़ने और उनमें बदलाव करने की अनुमति भी मिलती है. इस पेज पर, फ़ाइलों के साथ इंटरैक्ट करने के लिए JavaScript का इस्तेमाल करने का तरीका बताया गया है.
File System Access API का नया वर्शन
File System Access API, उपयोगकर्ता के स्थानीय सिस्टम पर मौजूद फ़ाइलों और डायरेक्ट्री को पढ़ने और उनमें डेटा सेव करने का तरीका उपलब्ध कराता है. यह Chrome और Edge जैसे ज़्यादातर Chromium पर आधारित ब्राउज़र में उपलब्ध है. इसके बारे में ज़्यादा जानने के लिए, File System Access API लेख पढ़ें.
File System Access API सभी ब्राउज़र के साथ काम नहीं करता. इसलिए, हमारा सुझाव है कि आप browser-fs-access का इस्तेमाल करें. यह एक हेल्पर लाइब्रेरी है. यह नई एपीआई का इस्तेमाल तब करती है, जब वह उपलब्ध होती है. साथ ही, जब वह उपलब्ध नहीं होती, तो पुराने तरीकों का इस्तेमाल करती है.
फ़ाइलों के साथ काम करना, क्लासिक तरीका
इस गाइड में, JavaScript के पुराने तरीकों का इस्तेमाल करके, फ़ाइलों के साथ इंटरैक्ट करने का तरीका बताया गया है.
फ़ाइलें चुनें
फ़ाइलें चुनने के दो मुख्य तरीके हैं: एचटीएमएल इनपुट एलिमेंट का इस्तेमाल करना और ड्रैग-एंड-ड्रॉप ज़ोन का इस्तेमाल करना.
एचटीएमएल इनपुट एलिमेंट
उपयोगकर्ताओं के लिए फ़ाइलें चुनने का सबसे आसान तरीका, <input type="file">
एलिमेंट का इस्तेमाल करना है. यह हर बड़े ब्राउज़र में काम करता है. इस पर क्लिक करने पर, उपयोगकर्ता अपने ऑपरेटिंग सिस्टम के फ़ाइल चुनने वाले यूज़र इंटरफ़ेस (यूआई) का इस्तेमाल करके, एक या एक से ज़्यादा फ़ाइलें चुन सकता है. हालांकि, ऐसा तब ही किया जा सकता है, जब
multiple
एट्रिब्यूट शामिल किया गया हो. जब उपयोगकर्ता एक या एक से ज़्यादा फ़ाइलें चुन लेता है, तो एलिमेंट का change इवेंट ट्रिगर हो जाता है. event.target.files से, फ़ाइलों की सूची ऐक्सेस की जा सकती है. यह एक FileList ऑब्जेक्ट है.
FileList में मौजूद हर आइटम एक File ऑब्जेक्ट होता है.
<!-- The `multiple` attribute lets users select multiple files. -->
<input type="file" id="file-selector" multiple>
<script>
const fileSelector = document.getElementById('file-selector');
fileSelector.addEventListener('change', (event) => {
const fileList = event.target.files;
console.log(fileList);
});
</script>
यहां दिए गए उदाहरण में, उपयोगकर्ता अपने ऑपरेटिंग सिस्टम के फ़ाइल चुनने वाले यूज़र इंटरफ़ेस (यूआई) का इस्तेमाल करके, एक से ज़्यादा फ़ाइलें चुन सकता है. इसके बाद, चुनी गई हर फ़ाइल को कंसोल में लॉग किया जाता है.
उपयोगकर्ताओं के लिए, चुनी जा सकने वाली फ़ाइलों के टाइप सीमित करना
कुछ मामलों में, आपको उपयोगकर्ताओं के लिए, चुनी जा सकने वाली फ़ाइलों के टाइप सीमित करने पड़ सकते हैं. उदाहरण के लिए, इमेज एडिटिंग ऐप्लिकेशन को सिर्फ़ इमेज स्वीकार करनी चाहिए, न कि टेक्स्ट फ़ाइलें. फ़ाइल टाइप की पाबंदियां सेट करने के लिए, इनपुट एलिमेंट में
accept
एट्रिब्यूट जोड़ें. इससे यह तय किया जा सकेगा कि किन फ़ाइल टाइप को स्वीकार किया जाएगा:
<input type="file" id="file-selector" accept=".jpg, .jpeg, .png">
पसंद के मुताबिक ड्रैग-एंड-ड्रॉप
कुछ ब्राउज़र में, <input type="file"> एलिमेंट, ड्रॉप टारगेट भी होता है,
इससे उपयोगकर्ता, आपके ऐप्लिकेशन में फ़ाइलें ड्रैग-एंड-ड्रॉप कर सकते हैं. हालांकि, यह ड्रॉप टारगेट
छोटा होता है और इसका इस्तेमाल करना मुश्किल हो सकता है. इसके बजाय, मुख्य सुविधाएं उपलब्ध कराने के बाद, आप एक बड़ा, पसंद के मुताबिक ड्रैग-एंड-ड्रॉप
सर्फ़ेस उपलब्ध करा सकते हैं, जिसके लिए आप
एक <input type="file"> एलिमेंट का इस्तेमाल कर सकते हैं.
अपना ड्रॉप ज़ोन चुनें
आपका ड्रॉप सर्फ़ेस, आपके ऐप्लिकेशन के डिज़ाइन पर निर्भर करता है. हो सकता है कि आपको सिर्फ़ विंडो के किसी हिस्से को ड्रॉप सर्फ़ेस बनाना हो. हालांकि, पूरी विंडो का इस्तेमाल किया जा सकता है.
इमेज कंप्रेस करने वाला ऐप्लिकेशन Squoosh, उपयोगकर्ता को विंडो में कहीं भी इमेज ड्रैग करने की सुविधा देता है. साथ ही, <input type="file">
एलिमेंट को शुरू करने के लिए, कोई इमेज चुनें पर क्लिक करने की सुविधा देता है. ड्रॉप ज़ोन के तौर पर जो भी चुना जाए, पक्का करें कि उपयोगकर्ता को यह साफ़ तौर पर पता हो कि वे उस सर्फ़ेस पर फ़ाइलें ड्रैग कर सकते हैं.
ड्रॉप ज़ोन तय करना
किसी एलिमेंट को ड्रैग-एंड-ड्रॉप ज़ोन के तौर पर इस्तेमाल करने के लिए, दो इवेंट के लिए लिसनर बनाएं: dragover
और drop.
dragover इवेंट, ब्राउज़र के यूज़र इंटरफ़ेस (यूआई) को अपडेट करता है. इससे यह साफ़ तौर पर पता चलता है कि ड्रैग-एंड-ड्रॉप ऐक्शन से, फ़ाइल की एक कॉपी बन रही है. जब उपयोगकर्ता, फ़ाइलें सर्फ़ेस पर ड्रॉप करता है, तो drop इवेंट ट्रिगर हो जाता है. इनपुट एलिमेंट की तरह, आप
event.dataTransfer.files से फ़ाइलों की सूची ऐक्सेस कर सकते हैं, जो एक
FileList ऑब्जेक्ट है. FileList में मौजूद हर
आइटम एक File ऑब्जेक्ट होता है.
const dropArea = document.getElementById('drop-area');
dropArea.addEventListener('dragover', (event) => {
event.stopPropagation();
event.preventDefault();
// Style the drag-and-drop as a "copy file" operation.
event.dataTransfer.dropEffect = 'copy';
});
dropArea.addEventListener('drop', (event) => {
event.stopPropagation();
event.preventDefault();
const fileList = event.dataTransfer.files;
console.log(fileList);
});
event.stopPropagation()
और event.preventDefault()
से, ब्राउज़र का डिफ़ॉल्ट व्यवहार बंद हो जाता है. इसके बाद, आपका कोड चलता है. इनके बिना, ब्राउज़र आपके पेज से हट जाएगा और उन फ़ाइलों को खोल देगा जिन्हें उपयोगकर्ता ने ब्राउज़र विंडो में ड्रॉप किया है.
लाइव डेमो के लिए, पसंद के मुताबिक ड्रैग-एंड-ड्रॉप लेख पढ़ें.
डायरेक्ट्री के बारे में क्या?
दुर्भाग्य से, JavaScript का इस्तेमाल करके, डायरेक्ट्री को ऐक्सेस करने का कोई बेहतर तरीका नहीं है.
The webkitdirectory
एट्रिब्यूट से, उपयोगकर्ता एक या एक से ज़्यादा डायरेक्ट्री चुन सकता है.<input type="file"> यह ज़्यादातर बड़े ब्राउज़र में काम करता है.
हालांकि, यह Android के लिए Firefox और iOS पर Safari में काम नहीं करता.
अगर ड्रैग-एंड-ड्रॉप की सुविधा चालू है, तो हो सकता है कि कोई उपयोगकर्ता, डायरेक्ट्री को ड्रॉप ज़ोन में ड्रैग करने की कोशिश करे. जब ड्रॉप इवेंट ट्रिगर होता है, तो इसमें डायरेक्ट्री के लिए एक File ऑब्जेक्ट शामिल होता है. हालांकि, इससे डायरेक्ट्री में मौजूद किसी भी फ़ाइल को ऐक्सेस नहीं किया जा सकता.
फ़ाइल का मेटाडेटा पढ़ना
The File ऑब्जेक्ट में, फ़ाइल के बारे में मेटाडेटा होता है. ज़्यादातर ब्राउज़र, फ़ाइल का नाम, उसका साइज़, और एमआईएमई टाइप उपलब्ध कराते हैं. हालांकि, प्लैटफ़ॉर्म के हिसाब से, अलग-अलग ब्राउज़र, अलग-अलग या ज़्यादा जानकारी उपलब्ध करा सकते हैं.
function getMetadataForFileList(fileList) {
for (const file of fileList) {
// Not supported in Safari for iOS.
const name = file.name ? file.name : 'NOT SUPPORTED';
// Not supported in Firefox for Android or Opera for Android.
const type = file.type ? file.type : 'NOT SUPPORTED';
// Unknown cross-browser support.
const size = file.size ? file.size : 'NOT SUPPORTED';
console.log({file, name, type, size});
}
}
इसे input-type-file
डेमो में देखा जा सकता है.
किसी फ़ाइल का कॉन्टेंट पढ़ना
FileReader का इस्तेमाल करके, File ऑब्जेक्ट के कॉन्टेंट को मेमोरी में
पढ़ें. आप FileReader को, किसी फ़ाइल को ऐरे बफ़र, डेटा यूआरएल या टेक्स्ट के तौर पर पढ़ने के लिए कह सकते हैं:
function readImage(file) {
// Check if the file is an image.
if (file.type && !file.type.startsWith('image/')) {
console.log('File is not an image.', file.type, file);
return;
}
const reader = new FileReader();
reader.addEventListener('load', (event) => {
img.src = event.target.result;
});
reader.readAsDataURL(file);
}
इस उदाहरण में, उपयोगकर्ता की ओर से उपलब्ध कराई गई File को पढ़ा जाता है. इसके बाद, उसे डेटा यूआरएल में बदला जाता है. साथ ही, उस डेटा यूआरएल का इस्तेमाल करके, img एलिमेंट में इमेज दिखाई जाती है.
यह पुष्टि करने का तरीका जानने के लिए कि उपयोगकर्ता ने इमेज फ़ाइल चुनी है या नहीं, read-image-file डेमो देखें.
फ़ाइल को पढ़ने की प्रोग्रेस पर नज़र रखना
बड़े साइज़ वाली फ़ाइलें पढ़ते समय, उपयोगकर्ता को यह बताने के लिए कुछ यूएक्स उपलब्ध कराना मददगार हो सकता है कि फ़ाइल को कितना पढ़ा जा चुका है. इसके लिए, progress
इवेंट का इस्तेमाल करें जो FileReader की ओर से उपलब्ध कराया गया है. progress इवेंट में दो प्रॉपर्टी होती हैं: loaded (पढ़ी गई मात्रा) और total (पढ़ने के लिए बाकी मात्रा).
function readFile(file) {
const reader = new FileReader();
reader.addEventListener('load', (event) => {
const result = event.target.result;
// Do something with result
});
reader.addEventListener('progress', (event) => {
if (event.loaded && event.total) {
const percent = (event.loaded / event.total) * 100;
console.log(`Progress: ${Math.round(percent)}`);
}
});
reader.readAsDataURL(file);
}