איך מקבלים קבצים ששותפו

פלאנס ליאו
פלאנס ליאו

הדרך המודרנית

שימוש ב-Web Share Target API

קודם כול, צריך להצהיר על share_target במניפסט של אפליקציית האינטרנט, המפרט את action (כתובת ה-URL שלך שמטפלת בקבצים משותפים), method ("POST" לקבצים) ו-enctype ("multipart/form-data" לקבצים) ואובייקט params שמכיל מאפיין files עם מערך של אובייקטים עם מערך של אובייקטים עם המאפיין name ו-accept, שמפרטים את סוגי הקבצים שניתן לשתף ואת השם להשגתם.

{
  "share_target": {
    "action": "/receive-files/",
    "method": "POST",
    "enctype": "multipart/form-data",
    "params": {
      "files": [
        {
          "name": "image",
          "accept": ["image/jpeg", "image/png", "image/webp", "image/gif"]
        }
      ]
    }
  }
}

לאחר מכן צריך לטפל בבקשות POST נכנסות ב-Service Worker. הקובץ מאוחסן באופן זמני במטמון מדיה, כדי שניתן יהיה להשתמש בו בלקוח. כדי לעשות זאת, אפשר להפנות את האפליקציה לכתובת URL עם פרמטר שאילתה מיוחד של סמן, כמו share-target.

self.addEventListener('fetch', (fetchEvent) => {
  if (fetchEvent.request.url.endsWith('/receive-files/') && fetchEvent.request.method === 'POST') {
    return fetchEvent.respondWith(
      (async () => {
        const formData = await fetchEvent.request.formData();
        const image = formData.get('image');
        const keys = await caches.keys();
        const mediaCache = await caches.open(keys.filter((key) => key.startsWith('media'))[0]);
        await mediaCache.put('shared-image', new Response(image));
        return Response.redirect('./?share-target', 303);
      })(),
    );
  }
});

לבסוף, עליכם להשתמש בקובץ בלקוח.

window.addEventListener('load', async () => {
  if (location.search.includes('share-target')) {
    const keys = await caches.keys();
    const mediaCache = await caches.open(
      keys.filter((key) => key.startsWith('media'))[0],
    );
    const image = await mediaCache.match('shared-image');
    if (image) {
      const blob = await image.blob();
      await mediaCache.delete('shared-image');
      // Handle the shared file somehow.
    }
  }
});

תמיכה בדפדפן

  • 89
  • 89
  • x
  • x

מקור

קריאה נוספת

הדגמה (דמו)

HTML

<!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 receive shared files</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 receive shared files</h1>
    <p>Install the app. After the installation, try sharing an image to it from another app.
  </body>
</html>

CSS


        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;
}
        

JS


        window.addEventListener('load', async () => {
  if (location.search.includes('share-target')) {
    const keys = await caches.keys();
    const mediaCache = await caches.open(
      keys.filter((key) => key.startsWith('media'))[0],
    );
    const image = await mediaCache.match('shared-image');
    if (image) {
      const blob = await image.blob();
      await mediaCache.delete('shared-image');
      // Handle the shared file somehow.
    }
  }
});