Safari扩展中img标签src被替换为webkit-masked-url致图片显示异常
问题背景
我将适配Chrome、Firefox的Manifest V2浏览器扩展,通过xcrun safari-web-extension-converter工具转为Safari版本后,遇到异常:Content Script里使用<img src="browser.runtime.getURL('images/my-image.svg')">加载的图片,其src被替换为webkit-masked-url://hidden/,最终显示为带问号的蓝色方块。
已观察到的现象
- 所有图片的src都会被替换为该掩码URL,但部分图片因控制台出现「页面https://fr.wikipedia.org/wiki/Test被允许加载来自webkit-masked-url://hidden/的不安全内容」提示,能正常渲染
- 将无法显示的img标签复制粘贴到正常图片旁时,该图片又能正确渲染
- 已在
manifest.json的web_accessible_resources中声明图片资源,Xcode构建产物里图片位于Shared (Extension)/Resources/images目录;用CSSbackground-image加载图片可正常显示,但希望保留img标签方案
原因分析
这是Safari扩展资源隔离机制导致的问题:webkit-masked-url是Safari为分隔扩展资源与页面内容引入的中间层,当Content Script注入时机、页面CSP策略与Safari的资源映射逻辑冲突时,就会出现资源加载失败。复制粘贴后能显示,说明资源本身可访问,问题出在URL的处理时机或方式上。
解决方案
1. 动态创建Img元素并赋值Src
不要直接在HTML字符串中硬编码browser.runtime.getURL,改为通过JS动态创建元素并设置属性:
// 替换原HTML字符串写法 const img = document.createElement('img'); img.src = browser.runtime.getURL('images/my-image.svg'); // 将图片插入到目标位置 targetContainer.appendChild(img);
这种方式能让Safari正确处理扩展资源的URL映射,避免被替换为无效的掩码地址。
2. 优化web_accessible_resources声明格式
针对Manifest V2,明确指定资源可被访问的页面匹配规则,帮助Safari准确识别资源访问上下文:
"web_accessible_resources": [ { "resources": ["images/*.svg"], "matches": ["https://fr.wikipedia.org/*"] } ]
3. 延迟Img元素注入
若Content Script注入时机过早,页面CSP策略还未适配扩展资源,可等待页面加载完成后再注入图片:
// 等待页面DOM加载完成 window.addEventListener('DOMContentLoaded', () => { const img = document.createElement('img'); img.src = browser.runtime.getURL('images/my-image.svg'); document.body.appendChild(img); });
验证步骤
每次修改后,重新用safari-web-extension-converter转换扩展,在Xcode中执行Product > Clean Build Folder清理缓存后再运行,避免缓存干扰测试结果。
内容的提问来源于stack exchange,提问作者Luc Antoni

