Cách nhận tệp được chia sẻ

Palances Liao
Palances Liao

Phong cách hiện đại

Sử dụng API mục tiêu chia sẻ web

Trước tiên, hãy khai báo share_target trong tệp kê khai ứng dụng web của bạn để liệt kê action (URL của bạn giúp xử lý tệp được chia sẻ), method ("POST" cho tệp) và enctype ("multipart/form-data" cho tệp) và đối tượng params chứa thuộc tính files với một mảng các đối tượng có thuộc tính nameaccept liệt kê các loại tệp có thể chia sẻ và tên cần lấy các tệp đó.

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

Sau đó, bạn cần xử lý các yêu cầu POST được gửi đến trong trình chạy dịch vụ. Tệp được lưu trữ tạm thời trong bộ nhớ đệm nội dung nghe nhìn để có thể được sử dụng trong ứng dụng. Bạn có thể thực hiện việc này bằng cách chuyển hướng ứng dụng đến một URL bằng tham số truy vấn điểm đánh dấu đặc biệt như 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);
      })(),
    );
  }
});

Cuối cùng, bạn cần sử dụng tệp này trong ứng dụng.

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

Hỗ trợ trình duyệt

  • 89
  • 89
  • lần
  • lần

Nguồn

Tài liệu đọc thêm

Bản minh họa

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