نحوه مدیریت فایل های باز شده از کاوشگر فایل

کاخ لیائو
Palances Liao

روش مدرن

استفاده از API مدیریت فایل

ابتدا، ویژگی file_handlers را در مانیفست برنامه وب خود تعریف کنید. API مدیریت فایل از شما می‌خواهد که ویژگی action (یک URL مدیریت) و ویژگی accept را مشخص کنید، که یک شیء با انواع MIME به عنوان کلید و آرایه‌هایی از پسوندهای فایل مربوطه است.

{
  "file_handlers": [
    {
      "action": "./",
      "accept": {
        "image/*": [".jpg", ".jpeg", ".png", ".webp", ".svg"]
      }
    }
  ]
}

در مرحله بعد، باید از API مدیریت فایل برای مدیریت فایل‌های باز شده از طریق launchQueue استفاده کنید.

if ('launchQueue' in window && 'files' in LaunchParams.prototype) {
  launchQueue.setConsumer((launchParams) => {
    if (!launchParams.files.length) {
      return;
    }
    for (const fileHandle of launchParams.files) {
      // Handle the file.
    }
  });
}

Browser Support

  • کروم: ۱۰۲.
  • لبه: ۱۰۲.
  • فایرفاکس: پشتیبانی نمی‌شود.
  • سافاری: پشتیبانی نمی‌شود.

Source

روش کلاسیک

استفاده از متد کلاسیک DataTransferItem.getAsFile()

اگر API مدیریت فایل پشتیبانی نمی‌شود، همچنان می‌توانید فایل‌ها را از فایل اکسپلورر به داخل برنامه بکشید و رها کنید. متد DataTransferItem.getAsFile() شیء File مربوط به آیتم داده‌ی درگ شده را برمی‌گرداند. اگر آیتم فایل نباشد، این متد null را برمی‌گرداند. در حالی که می‌توانید فایل را بخوانید، هیچ راهی برای نوشتن مجدد در آن وجود ندارد. این متد این عیب را دارد که از دایرکتوری‌ها پشتیبانی نمی‌کند.

Browser Support

  • کروم: ۱۱.
  • لبه: ۱۲.
  • فایرفاکس: ۵۰.
  • سافاری: ۵.۱.

Source

بهبود تدریجی

قطعه کد زیر در صورت موجود بودن از رابط برنامه‌نویسی کاربردی مدیریت فایل (File Handling API) استفاده می‌کند و علاوه بر آن، کنترل‌کننده‌های کشیدن و رها کردن (drag and drop handlers) را ثبت می‌کند تا فایل‌های کشیده شده (drag شده) قابل مدیریت باشند.

انواع فایل‌هایی که می‌توانند در مانیفست برنامه وب مدیریت شوند را اعلام کنید. مرورگرهایی که از API مدیریت فایل پشتیبانی نمی‌کنند، این را نادیده می‌گیرند.

{
  "file_handlers": [
    {
      "action": "./",
      "accept": {
        "image/*": [".jpg", ".jpeg", ".png", ".webp", ".svg"]
      }
    }
  ]
}
// File Handling API
const handleLaunchFiles = () => {
  window.launchQueue.setConsumer((launchParams) => {
    if (!launchParams.files.length) {
      return;
    }
    launchParams.files.forEach(async (handle) => {
      const file = await handle.getFile();
      console.log(`File: ${file.name}`);
      // Do something with the file.
    });
  });
};

if ('launchQueue' in window && 'files' in LaunchParams.prototype) {
  handleLaunchFiles();
}

// This is the drag and drop zone.
const elem = document.querySelector('main');
// Prevent navigation.
elem.addEventListener('dragover', (e) => {
  e.preventDefault();
});
// Visually highlight the drop zone.
elem.addEventListener('dragenter', (e) => {
  elem.style.outline = 'solid red 1px';
});
// Visually unhighlight the drop zone.
elem.addEventListener('dragleave', (e) => {
  elem.style.outline = '';
});
// This is where the drop is handled.
elem.addEventListener('drop', async (e) => {
  // Prevent navigation.
  e.preventDefault();
  // Unhighlight the drop zone.
  elem.style.outline = '';
  // Prepare an array of promises…
  const fileHandlesPromises = [...e.dataTransfer.items]
    // …by including only files (where file misleadingly means actual file _or_
    // directory)…
    .filter((item) => item.kind === 'file')
    // …and, depending on previous feature detection…
    .map((item) => item.getAsFile());
  // Loop over the array of promises.
  for await (const handle of fileHandlesPromises) {
    // This is where we can actually exclusively act on the files.
    if (handle.isFile) {
      console.log(`File: ${handle.name}`);
      // Do something with the file.
    }
  }
});

مطالعه بیشتر

نسخه آزمایشی

اچ‌تی‌ام‌ال

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <link rel="manifest" href="manifest.json" />
    <title>How to handle files opened from the file explorer</title>
    <link rel="stylesheet" href="style.css" />
    <!-- TODO: Devsite - Removed inline handlers -->
    <!-- <script>
      if ('serviceWorker' in navigator) {
        window.addEventListener('load', async () => {
          const registration = await navigator.serviceWorker.register(
            'sw.js',
          );
          console.log(
            'Service worker registered for scope',
            registration.scope,
          );
        });
      }
    </script>
    <script src="script.js" type="module"></script> -->
  </head>
  <body>
    <h1>How to handle files opened from the file explorer</h1>
    <p>Install the app. After the installation, try opening an image file from the file explorer with the app.
  </body>
</html>

سی اس اس


        html {
  box-sizing: border-box;
  font-family: system-ui, sans-serif;
  color-scheme: dark light;
}

*, *:before, *:after {
  box-sizing: inherit;
}

body {
  margin: 1rem;
}

img {
  height: auto;
  max-width: 100%;
  display: block;
}
        

جی‌اس


        if ('launchQueue' in window && 'files' in LaunchParams.prototype) {
  launchQueue.setConsumer((launchParams) => {
    if (!launchParams.files.length) {
      return;
    }
    for (const fileHandle of launchParams.files) {
      document.body.innerHTML += `

${fileHandle.name}

`; } }); }