วิธีรับไฟล์ที่แชร์

พาเลนซ์ เหลียว
Palances Liao

ก่อนอื่น ให้ประกาศ share_target ในไฟล์ Manifest ของเว็บแอปที่แสดงรายการ 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 ขาเข้าในโปรแกรมทำงานของบริการ ระบบจะจัดเก็บไฟล์ไว้ในแคชสื่อชั่วคราวเพื่อให้ใช้งานได้ในไคลเอ็นต์ ซึ่งทำได้โดยการเปลี่ยนเส้นทางแอปไปยัง 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

แหล่งที่มา

อ่านเพิ่มเติม

เดโม

<!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>

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

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