Chrome 扩展将 jquery 注入 iframe

Posted

技术标签:

【中文标题】Chrome 扩展将 jquery 注入 iframe【英文标题】:Chrome extension inject jquery into iframe 【发布时间】:2016-10-09 11:54:20 【问题描述】:

我正在尝试将 jquery 插入位于我的内容脚本中的 iframe。问题是 jquery ui 确实被加载但只返回一条消息“未定义 Jquery”。我怀疑它与加载 jquery 所需的时间有关。我是否需要设置一个时间间隔才能等待 jquery 被加载?或者有什么替代方法可以让我立即使用 jquery 而无需等待?我还尝试从我的后台脚本执行 jquery 脚本,但没有成功。

内容脚本

var jsjq = iframe.contentDocument.createElement("script")
    jsjq.src = chrome.extension.getURL("jquery.min.js")
    jsjq.type = "text/javascript"
var jsui = iframe.contentDocument.createElement("script")
    jsui.src = chrome.extension.getURL("jquery-ui.min.js")
    jsui.type = "text/javascript"
var css = iframe.contentDocument.createElement("link")
    css.href = chrome.extension.getURL("content.css")
    css.type = "text/css"
    css.rel = "stylesheet"
var cssui = iframe.contentDocument.createElement("link")
    cssui.href = chrome.extension.getURL("jquery-ui.min.css")
    cssui.type = "text/css"
    cssui.rel = "stylesheet"

iframe.contentWindow.document.head.appendChild(jsjq)
iframe.contentWindow.document.head.appendChild(jsui)
iframe.contentWindow.document.head.appendChild(css)
iframe.contentWindow.document.head.appendChild(cssui)

var script = iframe.contentWindow.document.createElement('script')
script.type = "text/javascript"
script.innerhtml = 'if (window.jQuery) console.log("st") else console.log("none")'
iframe.contentWindow.document.head.appendChild(script)

后台脚本

chrome.tabs.executeScript(sender.tab.id,   
    file: "content.js"
, function() 
chrome.tabs.executeScript(sender.tab.id,   // this part does not seem to work at all
    file: "jquery.min.js"
))

清单

"background": 
    "scripts": ["background.js"]    
,

"content_scripts": [
    
        "matches": ["<all_urls>"],
        "css": ["content.css", "jquery-ui.min.css"],
        "js": ["content.js", "jquery.min.js", "jquery-ui.min.js", "async.js"]

    
],

"web_accessible_resources": [
    "content.css", 
    "jquery.min.js",
    "jquery-ui.min.js", 
    "jquery-ui.min.css"     
]

【问题讨论】:

【参考方案1】:

我建议先通读this answer。等待 jQuery 加载取决于您如何加载它,这些方法中的每一种都有其优点和缺点。

通过脚本标签:

var jsjq = iframe.contentDocument.createElement("script");
    jsjq.src = chrome.extension.getURL("jquery.min.js");
    jsjq.type = "text/javascript";
    jsjq.onload = loadJQUI;
function loadJQUI() 
    var jsui = iframe.contentDocument.createElement("script")
        jsui.src = chrome.extension.getURL("jquery-ui.min.js");
        jsui.type = "text/javascript";
    iframe.contentWindow.document.head.appendChild(jsui)

iframe.contentWindow.document.head.appendChild(jsjq);

(只有这个需要 web_accessible_resources)。

优点:您的脚本可以与其他脚本和 dom 交互。 缺点:您的脚本无法与后台交互或调用 chrome api。

通过内容脚本:

"content_script": [
    
        "matches": ["<all_urls>"],
        "js": ["jquery.min.js","jquery-ui.min.js"]
    
]

优点:您可以与 dom 交互并可以调用一些 chrome api。 缺点:您的脚本与页面的脚本是隔离的。

通过后台脚本:

chrome.tabs.executeScript(sender.tab.id,  file: "jquery.min.js" ,function() 
    chrome.tabs.executeScript(sender.tab.id,  file: "jquery-ui.min.js" );
);

优点:与内容脚本相同,您可以决定何时(以及是否)注入脚本。 缺点:与内容脚本相同,但您必须决定何时(以及是否)注入脚本。

你想要哪一个取决于你实际想要如何使用 jQuery。

【讨论】:

【参考方案2】:

请尝试在您的 Manifest 的后台权限内声明 jquery

示例:

"background": 
     "scripts": [
         "jquery.js",
         "background.js"
     ], 
     "pages": [
         "background.html"
     ] 

正如Declare Permissions 中所讨论的,“background”权限还可以让 Chrome 继续运行,直到用户明确退出 Chrome。请注意,在后台已说明,禁用的应用程序和扩展程序将被视为未安装。

除此之外,这篇 SO 帖子中给出的解释 - Chrome extension code vs Content scripts vs Injected scripts 帮助我更好地理解。它也可能对您的情况有所帮助。

【讨论】:

另一个 SO 答案会很好看。清单中的“背景”条目用于背景页面,与后台权限(他不需要)是分开的。并且将 jquery 添加到后台将使该文件第四次被包含,因此这里的正确答案确实需要讨论为什么不需要所有这些。

以上是关于Chrome 扩展将 jquery 注入 iframe的主要内容,如果未能解决你的问题,请参考以下文章

使用 JQuery 访问由 chrome 扩展注入的 iframe

当使用带有各种脚本的 Google Chrome 扩展注入 HTML 模板时,jQuery 似乎没有导入

无法使用 jquery 访问通过 google chrome 内容脚本注入的 iframe 的内容

如何通过 Chrome 扩展将 CSS 注入网页?

Chrome扩展将侧边栏注入页面

使用 JavaScript 将 Chrome 扩展注入 iFrame