Froala 4.0.12粘贴blob:https类型图片无法触发上传如何修复
问题根因
Froala 4.0 及以上版本调整了粘贴内容的安全校验逻辑:跨域来源的blob:协议地址会被浏览器判定为不可访问的本地资源,也就是控制台抛出的Not allowed to load local resource报错。3.x 版本没有增加这层跨域 blob 拦截逻辑,所以可以正常读取资源、触发上传流程;新版直接将跨域 blob 判定为不可信资源,跳过了文件读取步骤,只会把原始 blob 地址插入 DOM,最终既无法正常显示图片,也不会触发绑定的上传事件。
修复方案
方案1:手动拦截粘贴事件处理跨域blob图片(推荐)
在编辑器初始化时新增paste.after事件回调,绕过内置的校验逻辑,手动处理所有粘贴生成的 blob 格式图片,步骤如下:
- 遍历编辑器内所有带
data-fr-image-pasted="true"标记、src 为 blob 协议的图片标签 - 用 fetch 请求拉取 blob 地址对应的资源,请求配置
credentials: 'omit'避免跨域凭证拦截 - 将拉取到的 blob 资源转换为 File 对象,移除原有的失效裂图标签,手动触发编辑器的图片上传流程
可直接替换使用的初始化代码如下:
var editor = new FroalaEditor('div#froala-editor', { imageUploadURL: 'https://example.com/uploadImage', // 修正了原代码里少写一个斜杠的笔误 imageUploadRemoteUrls: true, events: { "paste.after": function () { const editor = this; // 匹配所有粘贴生成的blob格式图片 const pastedBlobImgs = editor.el.querySelectorAll('img[data-fr-image-pasted="true"][src^="blob:"]'); pastedBlobImgs.forEach(imgEl => { const blobSrc = imgEl.src; // 拉取blob资源 fetch(blobSrc, { credentials: 'omit' }) .then(res => res.blob()) .then(blobData => { // 转换为File对象适配上传逻辑 const imgFile = new File([blobData], `pasted-img-${Date.now()}.png`, { type: blobData.type || 'image/png' }); // 移除失效的裂图标签 imgEl.remove(); // 手动触发图片上传流程 editor.image.upload([imgFile]); }) .catch(() => { // 资源拉取失败时直接清理无效标签 imgEl.remove(); }); }); }, "image.beforeUpload": function (files) { var editor = this; if (files.length) { var reader = new FileReader(); reader.onload = function (e) { var result = e.target.result; editor.image.insert(result, null, null, editor.image.get()); }; reader.readAsDataURL(files[0]); } editor.popups.hideAll(); return false; } } });
方案2:关闭内置粘贴安全过滤(仅可信场景可用)
如果使用场景是内部系统、所有粘贴内容来源可信,可以通过初始化参数关闭内置的粘贴内容过滤,强制保留所有粘贴的图片标签,初始化时新增如下配置即可:
htmlAllowNestedTags: true, pastePlain: false, htmlUntouched: false
该方案会提升XSS注入风险,公网场景不建议使用。
补充说明
如果跨域blob的源站没有配置对应资源的CORS允许规则,前端无法通过任何方式拿到blob对应的文件内容,这种场景下只能引导用户先将图片保存到本地后再拖拽/选择上传。
内容的提问来源于stack exchange,提问作者Tom
相关产品推荐
相关产品推荐

