前言
有時候,我們希望能訪問使用者的剪下板,來實現一些方便使用者的功能;但是另一方面,剪下板裡的資料對使用者來說又是非常隱私的,所以瀏覽器在獲取資訊方面有安全限制,同時也提供訪問介面。
前段時間由於業務功能,需要實現當使用者在富文字里進行貼上操作的時候,如果使用者複製的是圖片,需要將圖片上傳伺服器後,插入到文字內;看似合情合理的要求,卻有很多坑
一、什麼時候能訪問剪下板
1、在使用者觸發 onPaste 事件時(只能是使用者進行事件觸發),通過事件物件(event)獲取。官方文件
let text = (event.clipboardData || window.clipboardData).getData('text');
複製程式碼
2、Chrome 新增非同步剪貼簿 API,可以跟使用者申請訪問許可權,得到允許後則能訪問。參考知乎的一篇文章
二、訪問剪下板裡的圖片
先說結論
從檔案系統複製圖片 | mac os能拿到最後一張;windows 拿不到資料 |
---|---|
截圖 | mac 和 windows 能獲取 |
在瀏覽器介面複製 | mac 和 windows 能獲取 |
windows 為什麼一張都拿不到呢,使用者在檔案系統複製的檔案,在剪下板裡存的並不是圖片(猜測存的是圖片的標記),所以是拿不到。
程式碼如下
/**
* 觸發 paste 事件,響應方法
*/
function paste(event) {
// 拿到資料
let items = (event.clipboardData || event.originalEvent.clipboardData).items;
let imgList = []; // 獲得圖片資料,可以直接寫入到 <img src=''> 的src內進行展示
let strList = [];
for (let item of items) {
// 如果拿到的資料是檔案
if (item.kind === 'file') {
let blob = item.getAsFile();
let reader = new FileReader();
blobList.push(blob);
reader.onload = ()=> {
imgList.push(reader.result);
}
reader.readAsDataURL(blob);
} else if(item.kind === 'string') {
// 如果拿到的資料是字串
item.getAsString((s)=>{
strList.push(s);
});
}
}
}
複製程式碼
最後,想要完全實現使用者 Contr+C、Contr+V 來發帖,目前還做不到。有一種替代方案,將圖片拖動到富文字區域,這個操作也是很方便的,瀏覽器也都支援。
另外有一個公司的商業產品,他家開發的瀏覽器外掛能支援在桌面複製圖片後,貼上到瀏覽器裡。可惜目前只支援 windows 系統,mac os 還沒有提供;
他們的方案我大致猜測是:安裝瀏覽器外掛並且允許執行後,當你在瀏覽器觸發paste貼上事件後,js呼叫外掛方法,外掛去訪問系統裡的檔案(外掛其實也是windows 的一個軟體,所以能訪問檔案系統),然後返回給頁面的 js。