瀏覽器原生剪貼板:原來它能這樣讀取用戶截圖!
當我們使用 GitHub 時,會發現 Ctrl+V 就能直接讀取用戶剪貼板圖片進行粘貼,那么它是如何工作的?安全性如何?

一、新一代神器:navigator.clipboard
navigator.clipboard API 是一個異步的、基于 Promise 的現代接口,其具有三大核心優勢:
- 所有讀寫操作都返回 Promise,不會阻塞頁面
- 操作剪貼板需要獲得用戶授權,既安全又透明
- 除了文本,它能輕松讀寫圖片等二進制數據
二、寫入剪貼板
在深入讀取操作前,我們先看看如何向剪貼板寫入內容。
1. 寫入文本
這是最常見的操作,比如實現一個“點擊復制”按鈕。
const copyBtn = document.getElementById('copy-btn');
copyBtn.addEventListener('click', async () => {
try {
await navigator.clipboard.writeText('你好,世界!');
console.log('文本已成功復制到剪貼板');
} catch (err) {
console.error('復制失敗: ', err);
}
});2. 寫入圖片
寫入圖片稍微復雜一點,需要使用 clipboard.write() 方法,并傳入一個 ClipboardItem 對象。這個對象可以包含不同 MIME 類型的數據。

三、讀取剪貼板
當用戶在我們的網頁上執行粘貼操作時,我們如何讀取剪貼板里的內容,特別是圖片?
1. 關鍵:獲取用戶授權
這是最重要的一步。當我們嘗試讀取剪貼板時,瀏覽器會主動彈出提示框,請求用戶授權。
只有用戶點擊“允許”,我們的代碼才能繼續執行。這徹底杜絕了惡意網站在后臺偷偷讀取用戶剪貼板內容的可能。
2. 讀取步驟詳解
讓我們來實現一個監聽粘貼事件并處理圖片的功能。
- 監聽 paste 事件
- 調用 navigator.clipboard.read():該方法會返回 Promise,解析為一個 ClipboardItem 對象的數組
- 檢查每個 ClipboardItem MIME 類型
- 獲取數據 Blob:如果 MIME 中包含我們想要的圖片類型(如 "image/png"),我們就可以調用 item.getType() 方法解析為該數據的 Blob 對象
- 拿到 Blob 對象后,最常見的做法是使用 URL.createObjectURL() 生成一個臨時 URL,并將其顯示在 <img> 標簽中,或直接上傳到服務器
3. 完整代碼示例
假設我們有這樣一個 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,你會看到瀏覽器彈出權限請求。授權后,圖片就會立刻顯示在下方!
























