網頁呼叫原生分享實作
當看到富含趣味性的網頁是否會分享給周遭的朋友?使用智慧型裝置,是否有想要分享到裝置中已安裝的軟體,但頁面中沒有開放更多性的分享方式的困擾。
其實部分裝置與瀏覽器已開放呼叫原生分享API。
什麼是原生分享
使用原生分享會出現裝置才有的 APP 或系統功能,如 macOS 、 iOS 系統會出現 AirDrop,目前分為一般常見的「分享文字、網址」,以及「分享檔案」兩種。
其實原生分享就如同按下瀏覽器APP的分享,分享網址的效果是相同的。
分析
原生分享的優點
- 不會跳出網頁,降低網頁的跳出率
- 智慧型裝置使用者較習慣的分享介面
- 有更多性的選擇,會出現裝置已安裝的APP
原生分享的缺點
- 有瀏覽器、系統相容性問題
- 介面不能更改
- 原本的瀏覽器APP介面就已經有原生分享
考量
原生分享的電腦版本(Windows、macOS)介面效果較沒有很好用,以及缺乏社群性質的選擇,即使 macOS 可以增加原生分享項目,但操作介面上比較不吸引人,建議電腦仍維持客製化的設計介面,到手機才啟用原生分享。如果在手機想要保留原本設計的社群分享(如:FB、Line),可以增加更多分享按鈕的方式進行。
不管是否要保留原本客製化的分享項目,設計上都要考量「不支援(或不顯示)原生分享」的情況,要有能夠替代的方案。
瀏覽器相容性
分享文字、網址
- Safari:Safari 12+ (macOS與iOS系統)
- Chrome:Android Chrome 75+;電腦 Chrome 89+(限Windows與Chrome OS)
- Firefox:Android 92+,電腦系統目前不支援
- Edge:81+(限Windows系統)
- IE:微軟已宣布不再更新,因此IE不在考慮範圍
分享檔案
※較晚開發的功能,瀏覽器系統需求版本會比較高。
- Safari:Safari 15+(macOS與iOS系統)
- Chrome:Android Chrome 98+;電腦 Chrome 89+(不支援macOS)
- Firefox:Android 98+,電腦系統目前不支援
- Edge:89+(不支援macOS)
- IE:微軟已宣布不再更新,因此IE不在考慮範圍
※Safari: Can I use 顯示14+,經過測試後需要15+才能支援。
分享檔案有類型限制,目前只能分享圖片、音樂檔、影片檔、部分文字檔,詳細列表見 Permitted File Extensions in Chromium(來源:web.dev — Google 提供的文件)。
使用條件
條件一、網頁一定要為HTTPS
Google在2014就公布HTTPS會列入搜尋引擎的演算法之一,理論上專案應符合此條件。本機開發使用 localhost ,即使不是HTTPS也能呼叫(使用IP則需要其它工具輔助,見最下方QA)。
條件二、要有明確的方式觸發
當使用者執行點擊按鈕(click
)時才能觸發(無法在頁面加載或setTimeout
執行),以確保使用上的安全性。
實作
實作:分享網址、文字
呼叫 navigator.share
,如果支援才執行:
const shareButton = document.querySelector('#share-button');
el.addEventListener('click', function (event) {
if (navigator.share) {
navigator
.share({
title: '分享標題',
text: '分享文字敘述',
url: '分享連結',
})
// 成功開啟原生分享
.then(() => console.log('分享成功'))
// 分享錯誤後的事件
.catch((error) => console.log('分享錯誤:', error));
}
});
搭配 async
, await
寫法(來源:W3C文件)
shareButton.addEventListener('click', async () => {
try {
await navigator.share({ title: '分享標題', url: '' });
console.log('分享成功');
} catch (error) {
console.error('分享錯誤:', error.message);
}
});
實作:分享檔案
確認 navigator.canShare
可呼叫、確認檔案:
const shareButton = document.querySelector('#share-button');
const inputFile = document.querySelector('#input-file');shareButton.addEventListener('click', function (event) {
// filesArray
// 1. 從input取得資料
const filesArray = inputFile.files;
// 2. 或建立新的File資料
// const txt = new Blob(['Test'], {type: 'text/plain'});
// const filesArray = new File([txt], "test.txt"); // 分享
if (navigator.canShare && navigator.canShare({ files: filesArray })) {
navigator
.share({
title: '分享標題',
text: '分享文字敘述',
files: filesArray,
})
// 成功開啟原生分享
.then(() => console.log('分享成功'))
// 分享錯誤後的事件
.catch((error) => console.log('分享錯誤:', error));
}
});
其他實例分享
相關Q&A
原本APP介面中就有分享,為什麼還要另外做原生分享
主要是提供使用者完整性功能,一方面看規格是否有要求,如果沒有,則看開發者對於專案自我要求的完整性,以及時間上允許才製作。
是否捨棄原本的介面
還是可能會碰到不支援的情況,考量在不支援的情況下分享功能應該也要正常運作。
是否可以取得使用者成功分享的數據
目前 Windows 無法回傳「取消分享」之錯誤,程式中「成功」也只是「成功開啟原生分享」,至於使用者到底有沒有分享出去,不是所有裝置都能直接取得,需要串接第三方API(第三方也必須開放API權限)。如果很需要這類數據追蹤,建議使用大型的分享服務,如AddThis、AddToAny等。
如果開發用的測試站沒有HTTPS模式該怎麼測試
一定要用HTTPS模式才能使用,只能以解決「如何讓使用的虛擬主機有HTTPS模式」方向走。看購買的方案是否有支援子網域也有HTTPS模式,或是使用 SSL For Free 線上工具, Zero SSL 的特性:
- 要先申請帳號才能使用
- 免費方案能申請的數量有限(3個)
- 僅能撐三個月(90天),三個月後要重新申請
- 還是需要搭配虛擬主機後台才能安裝SSL
開發時,使用 localhost 要怎麼達成 HTTPS 條件
結語
寫這篇的目的在希望前期規劃與設計時,可以考量如何安插原生的分享按鈕,不然找地方塞程式,最後在串接後端時還會被移除,只能給個微笑。
如果喜歡這篇技術分享,歡迎留言或分享出去。
若是喜歡海棠設計的文章,歡迎分享、留言、按讚、關注海棠設計的粉絲團專頁。
感謝閱讀到最後的你。