共用方式為


與其他應用程式共享內容

在操作檔案或複製內容比在桌面操作系統上更不直覺的行動裝置,讓應用程式之間的共用內容變得很受歡迎。 例如,在行動裝置上,通常會透過傳送簡訊與朋友共用影像。 但共用內容不會保留給行動裝置;您也可以在 Windows 上的應用程式之間共用。

共用內容有兩個方向,而漸進式 Web 應用程式 (PWA 可) 處理這兩個方向:

方向 描述
共用內容 若要共用內容,PWA 會產生內容 (例如文字、連結或檔案) ,並將共用內容交給操作系統。 操作系統可讓使用者決定要用來接收該內容的應用程式。
接收共享內容 若要接收內容,PWA 會作為內容目標。 PWA 會向操作系統註冊為內容共享目標。

註冊為共用目標的 PWA 會以原生方式整合到 OS 中,而且更吸引使用者。

共用內容

PWA 可以使用 Web 共用 API 來觸發顯示作業系統共用對話方塊。

注意事項

Web 共用僅適用於透過 HTTPS (提供的網站,這是 PWA) 的情況,而且只能在回應使用者動作時叫用。

若要共用連結、文字或檔案等內容,請使用 navigator.share 函式,如下所示。 函 navigator.share 式接受至少應具有下列其中一個屬性的物件:

  • title:共用內容的簡短標題。
  • text:共用內容的較長描述。
  • url:要共用之資源的位址。
  • files:要共用的檔案陣列。
function shareSomeContent(title, text, url) {
  if (!navigator.share) {
    return;
  }

  navigator.share({title, text, url}).then(() => {
    console.log('The content was shared successfully');
  }).catch(error => {
    console.error('Error sharing the content', error);
  });
}

在上述程式代碼中,我們會先測試是否已定義 ,以 navigator.share 檢查瀏覽器是否支援 Web 共用。 函 navigator.share 式會傳回 Promise 物件,此物件會在共用成功時解析,並在發生錯誤時拒絕。

因為這裡使用 Promise,所以上述程式代碼可以重寫為 async 函式,如下所示:

async function shareSomeContent(title, text, url) {
  if (!navigator.share) {
    return;
  }

  try {
    await navigator.share({title, text, url});
    console.log('The content was shared successfully');
  } catch (e) {
    console.error('Error sharing the content', e);
  }
}

在 Windows 上,上述程式代碼會觸發共用對話方塊,讓使用者挑選應用程式以接收共享內容。 共用對話框如下所示:

Windows 上的共享對話框

一旦用戶選取要接收共用內容的應用程式,此應用程式必須以任何選擇的方式來處理它。 例如,電子郵件應用程式可能會使用 title 作為電子郵件主旨,並使用 text 作為電子郵件本文。

共用檔案

navigator.share 式也會接受數位 files 來與其他應用程式共用檔案。

在共用檔案之前,請務必先測試瀏覽器是否支援共用檔案。 若要檢查是否支援共用檔案,請使用 函式 navigator.canShare

function shareSomeFiles(files) {
  if (navigator.canShare && navigator.canShare({files})) {
    console.log('Sharing files is supported');
  } else {
    console.error('Sharing files is not supported');
  }
}

共用 files 物件成員必須是 對象的陣 File 列。 深入了解 檔案介面

建構 File 物件的其中一種方式是:

  1. 首先,使用 fetch API 來要求資源。
  2. 然後,使用傳回的回應來建立新的 File

該方法如下所示。

async function getImageFileFromURL(imageURL, title) {
  const response = await fetch(imageURL);
  const blob = await response.blob();
  return new File([blob], title, {type: blob.type});
}

在上述程式代碼中:

  1. getImageFileFromURL 式會使用 URL 擷取影像。
  2. response.blob() 式會將影像轉換成 BLOB) (二進位大型物件。
  3. 程序代碼 File 會使用 BLOB 建立 物件。

共用內容的示範

PWAmp 是示範 PWA,使用 navigator.share 函式來共用文字和連結。

若要測試共用功能:

  1. 移至 PWAmp

  2. 在網址列右側,按兩下 [可用的應用程式]。安裝 ([應用程式可用,安裝] 圖示) 按鈕以將 PWAmp 安裝為 PWA。

  3. 在已安裝的 PWAmp PWA 中,將本機音訊檔案拖曳至應用程式視窗) , (匯入本機音訊檔案。 例如,如果您已複製 MicrosoftEdge / Demos 存放庫,則在 (Demos 存放庫 > pwamp/首頁目錄中會有檔案的本地副本 .mp3) ,例如 C:\Users\username\GitHub\Demos\pwamp\songs

  4. 在新匯入的歌曲旁邊,按兩下 [歌曲動作 (...) ] 按鈕,然後選取 [ 共用]。 [Windows 共用] 對話框隨即顯示:

    [Windows 共用] 對話方塊,以挑選接收共用內容的應用程式

  5. 挑選要在其中共用內容的應用程式。

您可以在 GitHub 上找到 PWAmp 原始程式碼 。 PWAmp 應用程式會在 app.js 來源檔案中使用 Web 共用 API。

接收共享內容

藉由使用 Web 共用目標 API,PWA 可以註冊為系統共用對話框中的應用程式顯示。 PWA 接著可以使用 Web 共用目標 API 來處理來自其他應用程式的共享內容。

注意事項

只有已安裝的 PWA 可以註冊為共享目標。

註冊為目標

若要接收共享內容,第一件事就是將 PWA 註冊為共用目標。 若要註冊,請使用指令 share_target 清單成員。 安裝您的應用程式時,作業系統會使用 share_target 成員,將您的應用程式包含在系統共用對話框中。 操作系統知道當使用者挑選您的應用程式來共用內容時該怎麼辦。

成員 share_target 必須包含必要的資訊,系統才能將共用內容傳遞至您的應用程式。 請考慮下列指令清單程式代碼:

{
    "share_target": {
        "action": "/handle-shared-content/",
        "method": "GET",
        "params": {
            "title": "title",
            "text": "text",
            "url": "url",
        }
    }
}

當使用者選取您的應用程式作為共用內容的目標時,就會啟動 PWA。 HTTP GET 要求會對 屬性所指定的 action URL 提出。 共用數據會傳遞為 titletexturl 查詢參數。 提出下列要求: /handle-shared-content/?title=shared title&text=shared text&url=shared url

如果您有使用其他查詢參數名稱的現有程式代碼,您可以將預設 titletexturl 查詢參數對應至其他名稱。 在下列範例中 title,、 texturl 查詢參數會對應至 subjectbodyaddress

{
    "share_target": {
        "action": "/handle-shared-content/",
        "method": "GET",
        "params": {
            "title": "subject",
            "text": "body",
            "url": "address",
        }
    }
}

處理 GET 共用數據

若要處理 PWA 程式代碼中透過 GET 要求共用的數據,請使用 URL 建構函式來擷取查詢參數:

window.addEventListener('DOMContentLoaded', () => {
    console url = new URL(window.location);

    const sharedTitle = url.searchParams.get('title');
    const sharedText = url.searchParams.get('text');
    const sharedUrl = url.searchParams.get('url');
});

處理 POST 共享數據

如果共享資料是要以任何方式變更您的應用程式,例如更新儲存在應用程式中的某些內容,您必須使用 POST 方法,並使用 來定義編碼類型 enctype

{
    "share_target": {
        "action": "/post-shared-content",
        "method": "POST",
        "enctype": "multipart/form-data",
        "params": {
            "title": "title",
            "text": "text",
            "url": "url",
        }
    }
}

POST HTTP 要求包含以編碼的multipart/form-data共享數據。 您可以使用伺服器端程式代碼在 HTTP 伺服器上存取此數據,但是當使用者離線時,這無法運作。 若要提供更好的體驗,請使用服務背景工作角色,並使用 fetch 事件接聽程式從服務工作者存取數據,如下所示:

self.addEventListener('fetch', event => {
    const url = new URL(event.request.url);

    if (event.request.method === 'POST' && url.pathname === '/post-shared-content') {
        event.respondWith((async () => {
            const data = await event.request.formData();

            const title = data.get('title');
            const text = data.get('text');
            const url = data.get('url');

            // Do something with the shared data here.

            return Response.redirect('/content-shared-success', 303);
        })());
    }
});

在上述程式代碼中:

  1. 服務工作者會 POST 攔截要求。

  2. 以某種方式使用數據 (例如將內容儲存在本機) 。

  3. 將使用者重新導向至成功頁面。 如此一來,即使網路已關閉,應用程式仍可運作。 應用程式可以選擇只在本機儲存內容,或稍後在還原連線時將內容傳送至伺服器 (例如使用 背景同步) 。

處理共用檔案

應用程式也可以處理共用檔案。 若要處理 PWA 中的檔案,您必須使用 POST 方法和 multipart/form-data 編碼類型。 此外,您必須宣告應用程式可以處理的檔案類型。

{
    "share_target": {
        "action": "/store-code-snippet",
        "method": "POST",
        "enctype": "multipart/form-data",
        "params": {
            "title": "title",
            "files": [
                {
                    "name": "textFile",
                    "accept": ["text/plain", "text/html", "text/css", 
                               "text/javascript"]
                }
            ]
        }
    }
}

上述指令清單程式代碼會告訴系統,您的應用程式可以接受具有各種MIME類型的文字檔。 擴展名,例如 .txt,也可以在 陣列中 accept 傳遞。

若要存取共用檔案,請使用 formData 先前的要求,並使用 FileReader 來讀取內容,如下所示:

self.addEventListener('fetch', event => {
    const url = new URL(event.request.url);

    if (event.request.method === 'POST' && url.pathname === '/store-code-snippet') {
        event.respondWith((async () => {
            const data = await event.request.formData();

            const filename = data.get('title');
            const file = data.get('textFile');

            const reader = new FileReader();
            reader.onload = function(e) {
                const textContent = e.target.result;

                // Do something with the textContent here.

            };
            reader.readAsText(file);

            return Response.redirect('/snippet-stored-success', 303);
        })());
    }
});

另請參閱