項目使用 CKEditor 3.x,用戶從 Word、Excel、截圖工具複製內容(含圖片)粘貼到編輯器。粘貼後圖片以 data:image/png;base64... 或 file:// 本地路徑形式存在,提交表單時圖片無法顯示,需自動上傳至服務器並替換為線上 URL。
**CKEditor 4/5 內建支援**:升級至 CKEditor 4.5+ 或 CKEditor 5,配合 ImageUpload 插件與後端上傳接口,可自動處理粘貼圖片上傳。
CKEDITOR.replace('editor', {
// 配置上傳接口
filebrowserUploadUrl: '/api/upload/image',
// 或使用簡單上傳適配器 (需後端返回特定格式)
extraPlugins: 'imageupload',
// 自定義上傳邏輯 (CKEditor 4.5+)
imageUploadUrl: '/api/upload/image',
// 上傳成功後回調
filebrowserUploadMethod: 'form'
});
上傳成功返回 JSON:
{
"uploaded": 1,
"fileName": "image.png",
"url": "https://cdn.example.com/uploads/image.png"
}
失敗返回:
{
"uploaded": 0,
"error": { "message": "上傳失敗原因" }
}
若無法升級,需引入第三方插件或自行開發:
pastefromword、clipboard 增強插件。editor.on('paste', function(evt) {
var data = evt.data.dataValue; // 獲取粘貼的 HTML
// 正則提取 base64 圖片或 file:// 路徑
// 對每個圖片調用上傳 API
// 上傳成功後替換 data 中的 src
evt.data.dataValue = modifiedData;
});
file:// 路徑瀏覽器無法直接讀取,需用戶通過 <input type="file"> 選擇,或利用 Clipboard API (現代瀏覽器) 讀取 ClipboardItem。| 編輯器 | 粘貼上傳支援 | 遷移成本 |
|---|---|---|
| CKEditor 5 | ✅ 內建 ImageUpload、Clipboard | 中 (API 變化大) |
| TinyMCE 5/6 | ✅ images_upload_handler 配置簡單 | 中 |
| Quill | ✅ 模塊化配置 | 低 (API 簡潔) |
| Editor.js | ✅ 區塊化,圖片工具獨立上傳 | 高 (架構差異大) |
<div id="editor" contenteditable="true"></div>
<script>
document.getElementById('editor').addEventListener('paste', async (e) => {
e.preventDefault();
const items = e.clipboardData.items;
for (const item of items) {
if (item.type.startsWith('image/')) {
const file = item.getAsFile();
const formData = new FormData();
formData.append('file', file);
try {
const res = await fetch('/api/upload/image', { method: 'POST', body: formData });
const { url } = await res.json();
document.execCommand('insertImage', false, url);
} catch (err) {
console.error('上傳失敗', err);
}
} else {
// 非圖片內容直接粘貼純文本/HTML
const text = e.clipboardData.getData('text/html') || e.clipboardData.getData('text/plain');
document.execCommand('insertHTML', false, text);
}
}
});
</script>
此方案脫離編輯器框架,基於原生 Clipboard API 與 contenteditable,輕量且可控。
paste 事件,利用 Clipboard API 讀取圖片文件上傳並插入。file:// 路徑,現代瀏覽器均不允許 JS 讀取本地文件路徑。解決粘貼圖片上傳的核心是:**利用 Clipboard API 獲取文件對象,而非解析本地路徑**。