قراءة الملفات في JavaScript

يُعد تحديد الملفات على الجهاز المحلي للمستخدم والتفاعل معها أحد الميزات الأكثر استخدامًا على الويب. تسمح للمستخدمين بتحديد الملفات تحميلها إلى خادم، عند مشاركة الصور أو إرسال معلومات الضرائب مثلاً المستندات. كما يتيح للمواقع الإلكترونية قراءتها ومعالجتها بدون الحاجة إلى لنقل البيانات عبر الشبكة. تشرح هذه الصفحة كيفية استخدام جافا سكريبت للتفاعل مع الملفات.

واجهة برمجة التطبيقات File System Access API الحديثة

توفر واجهة برمجة تطبيقات File System Access API وسيلة للقراءة من الملفات والكتابة إليها على النظام المحلي للمستخدم. يتوفر في معظم الأنظمة المستندة إلى Chromium المتصفحات مثل Chrome وEdge. لمعرفة المزيد حول ذلك، راجع واجهة برمجة التطبيقات File System Access API:

نظرًا لعدم توافق واجهة برمجة التطبيقات File System Access API مع جميع المتصفحات، التي ننصح بها باستخدام browser-fs-access هي مكتبة مساعِدة تستخدم واجهة برمجة التطبيقات الجديدة أينما كانت متوفّرة ومتوفّرة إلى النُهج القديمة عندما لا يكون كذلك.

العمل على الملفات بالطريقة الكلاسيكية

يوضِّح لك هذا الدليل كيفية التفاعل مع الملفات باستخدام طرق JavaScript القديمة.

اختيار الملفات

هناك طريقتان أساسيتان لتحديد الملفات: استخدام عنصر إدخال HTML، واستخدام منطقة السحب والإفلات:

عنصر إدخال HTML

أسهل طريقة للمستخدمين لتحديد الملفات هي استخدام <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، وهو تطبيق ويب لضغط الصور.
Squoosh يجعل النافذة بأكملها منطقة إفلات.

يتيح تطبيق ضغط الصور 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.

webkitdirectory على العنصر <input type="file">، تتيح للمستخدم اختيار دليل أو الأدلة. هذا الملف متوافق في معظم المتصفحات الرئيسية باستثناء Firefox لنظامي التشغيل Android وSafari على iOS.

إذا تم تمكين السحب والإفلات، فقد يحاول المستخدم سحب دليل إلى الجديدة. عند تنشيط حدث الانخفاض، يتم تضمين كائن File الدليل، ولكنه لا يوفر إمكانية الوصول إلى أي من الملفات الموجودة في الدليل.

قراءة البيانات الوصفية للملف

يحتوي العنصر File على بيانات وصفية عن الملف. معظم المتصفحات على اسم الملف وحجمه ونوع MIME، على الرغم من ذلك على نظام التشغيل، قد توفر متصفحات مختلفة مختلفة المعلومات.

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 قراءة ملف على أنه مخزن مؤقت للمصفوفة، عنوان URL للبيانات أو نص:

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 التي قدّمها المستخدم، ثم يحوّلها إلى بيانات. عنوان URL، ويستخدم عنوان URL للبيانات من أجل عرض الصورة في عنصر 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);
}

صورة رئيسية للفنان "فنسنت بوتا" من موقع Unspark