Chrome扩展Manifest v3内容脚本无法修改iframe的UserAgent问题
Chrome扩展Manifest v2/v3 UserAgent修改差异问题
我正在开发一款Chrome扩展,已发布Manifest v2版本,同时也开发了Manifest v3版本,但两者存在一处功能差异:在特定测试页面中,v2能修改主窗口及iframe的UserAgent,v3仅能修改主窗口的UserAgent。
共用内容脚本
var AGScript = ` var setAgent = function(win) { try { Object.defineProperty(win.navigator, "userAgentData", {value:undefined}); Object.defineProperty(win.navigator, "platform", {value:undefined}); Object.defineProperty(win.navigator, "vendor", {value:undefined}); Object.defineProperty(win.navigator, "userAgent", {value:"xxx"}); Object.defineProperty(win.navigator, "appVersion", {value:"xxx"}); } catch(e) {} }; document.addEventListener("DOMContentLoaded", function(event) { setAgent(window); }); document.addEventListener("DOMNodeInserted", function(event) { if (event.target.tagName == "IFRAME") setAgent(event.target.contentWindow); }); setAgent(window); `; var script = document.createElement("script"); script.type = "text/javascript"; script.textContent = AGScript; document.documentElement.appendChild(script); script.remove();
Manifest v2配置
"content_scripts": [ { "all_frames": true, "js": [ "content-ag.js" ], "match_about_blank": true, "matches": [ "http://*/*", "https://*/*", "file:///*" ], "run_at": "document_start" } ]
Manifest v3配置
"content_scripts": [ { "all_frames": true, "js": [ "content-ag.js" ], "matches": [ "<all_urls>" ], "run_at": "document_start", "world": "MAIN" } ]
测试差异与初步判断
- 在javascript测试页面,v2版本可修改主窗口及iframe.contentWindow的UserAgent,但v3版本仅能修改主窗口的UserAgent。尝试调整多种清单配置仍无法解决。
- 在useragent测试页面,两个版本均可修改所有内容(包括iframe),因此判断这是一个时序问题。
更新后的问题
按照建议添加了"match_origin_as_fallback": true,并将内容脚本修改为自执行函数形式:
(() => { console.log("here!"); var setAgent = function(win) { try { Object.defineProperty(win.navigator, "userAgentData", {value:undefined}); Object.defineProperty(win.navigator, "platform", {value:undefined}); Object.defineProperty(win.navigator, "vendor", {value:undefined}); Object.defineProperty(win.navigator, "userAgent", {value:"xxx"}); Object.defineProperty(win.navigator, "appVersion", {value:"xxx"}); } catch(e) {} }; document.addEventListener("DOMContentLoaded", function(event) { setAgent(window); }); document.addEventListener("DOMNodeInserted", function(event) { if (event.target.tagName == "IFRAME") setAgent(event.target.contentWindow); }); setAgent(window); })()
但在useragent测试页面测试时,UserAgent仍未被覆盖,控制台已打印"here!",我是否哪里操作有误?(我在Manifest v2中测试,理论上不应有差异)
contentWindow拦截器相关问题
这段代码导致useragent测试网站报错:Cannot read properties of undefined (reading 'navigator'),报错代码如下:
function getUAs() { const frame = document.createElement("iframe"); frame.setAttribute("sandbox", "allow-same-origin"), frame.src = "javascript:false", frame.classList.add("hidden"), document.body.appendChild(frame); const {userAgent: userAgent, appVersion: appVersion} = frame.contentWindow.navigator; // 报错位置 return frame.remove(), [navigator.userAgent, _navigator.userAgent, "Mozilla/" + _navigator.appVersion, headerUA, userAgent, "Mozilla/" + appVersion] }
当我将const fp = wnd.HTMLIFrameElement.prototype;替换为const fp = wnd.HTMLElement.prototype;时,报错解决,但无法正常覆盖UserAgent。
内容的提问来源于stack exchange,提问作者Escape75
相关产品推荐
相关产品推荐

