當我們使用 GitHub 時,會發現 Ctrl+V 就能直接讀取用戶剪貼板圖片進行粘貼,那么它是如何工作的?安全性如何?
新一代神器:navigator.clipboard
navigator.clipboard
API 是一個異步的、基于 Promise 的現代接口,其具有三大核心優勢:
- 所有讀寫操作都返回 Promise,不會阻塞頁面
- 操作剪貼板需要獲得用戶授權,既安全又透明
- 除了文本,它能輕松讀寫圖片等二進制數據
寫入剪貼板
在深入讀取操作前,我們先看看如何向剪貼板寫入內容。
寫入文本
這是最常見的操作,比如實現一個“點擊復制”按鈕。
const copyBtn = document.getElementById('copy-btn');
copyBtn.addEventListener('click', async () => {
try {
await navigator.clipboard.writeText('你好,世界!');
console.log('文本已成功復制到剪貼板');
} catch (err) {
console.error('復制失敗: ', err);
}
});
寫入圖片
寫入圖片稍微復雜一點,需要使用 clipboard.write()
方法,并傳入一個 ClipboardItem
對象。這個對象可以包含不同 MIME 類型的數據。
讀取剪貼板
當用戶在我們的網頁上執行粘貼操作時,我們如何讀取剪貼板里的內容,特別是圖片?
關鍵:獲取用戶授權
這是最重要的一步。當我們嘗試讀取剪貼板時,瀏覽器會主動彈出提示框,請求用戶授權。
只有用戶點擊“允許”,我們的代碼才能繼續執行。這徹底杜絕了惡意網站在后臺偷偷讀取用戶剪貼板內容的可能。
讀取步驟詳解
讓我們來實現一個監聽粘貼事件并處理圖片的功能。
- 監聽
paste
事件 - 調用
navigator.clipboard.read()
:該方法會返回 Promise,解析為一個 ClipboardItem
對象的數組 - 檢查每個
ClipboardItem
MIME 類型 - 獲取數據
Blob
:如果 MIME 中包含我們想要的圖片類型(如 "image/png"
),我們就可以調用 item.getType()
方法解析為該數據的 Blob
對象 - 拿到
Blob
對象后,最常見的做法是使用 URL.createObjectURL()
生成一個臨時 URL,并將其顯示在 <img>
標簽中,或直接上傳到服務器
完整代碼示例
假設我們有這樣一個 HTML 結構:
<div id="paste-area" contenteditable="true">
<p>請在這里粘貼你的截圖...</p>
</div>
<img id="preview-image" src="" alt="圖片預覽" style="max-width: 100%; margin-top: 20px;">
對應的 JavaScript 代碼如下:
const pasteArea = document.getElementById('paste-area');
const previewImage = document.getElementById('preview-image');
pasteArea.addEventListener('paste', async (e) => {
// 阻止默認的粘貼行為
e.preventDefault();
try {
// 請求讀取剪貼板的權限
const permission = await navigator.permissions.query({ name: 'clipboard-read' });
if (permission.state === 'denied') {
throw new Error('剪貼板讀取權限被拒絕');
}
// 讀取剪貼板內容
const clipboardItems = await navigator.clipboard.read();
for (const item of clipboardItems) {
// 檢查是否有圖片類型
const imageType = item.types.find(type => type.startsWith('image/'));
if (imageType) {
// 獲取圖片 blob 數據
const blob = await item.getType(imageType);
// 創建一個臨時的 URL 來預覽圖片
const imageUrl = URL.createObjectURL(blob);
previewImage.src = imageUrl;
// 在這里,你可以將 blob 上傳到服務器
// uploadToServer(blob);
console.log('圖片粘貼成功!');
return; // 處理完圖片后即可退出
}
}
// 如果沒有圖片,可以嘗試讀取文本
const text = await navigator.clipboard.readText();
console.log('粘貼的文本內容:', text);
pasteArea.innerText = text;
} catch (err) {
console.error('粘貼失敗: ', err);
// 如果沒有圖片,嘗試用傳統方式讀取文本
const text = e.clipboardData.getData('text/plain');
if (text) {
pasteArea.innerText = text;
}
}
});
function uploadToServer(blob) {
const formData = new FormData();
formData.append('image', blob, 'screenshot.png');
// fetch('/api/upload', {
// method: 'POST',
// body: formData
// }).then(...);
console.log('正在模擬上傳...', formData.get('image'));
}
現在,截取一張圖到剪貼板,然后在這個區域按下 Ctrl+V
,你會看到瀏覽器彈出權限請求。授權后,圖片就會立刻顯示在下方!
該文章在 2025/7/30 9:48:46 編輯過