Chrome扩展程序:插入javascript标记并调用函数

时间:2011-05-09 18:58:26

标签: javascript function google-chrome background

我有一个使用内容脚本的Chrome扩展程序,以便动态插入引用an external javascript file的脚本标记。我使用的代码是:

var html_doc = document.getElementsByTagName('head')[0]; 
var _js = document.createElement('script');  
_js.setAttribute('type', 'text/javascript'); 
_js.setAttribute('id', 'chr_js'); 
_js.setAttribute('src', 'http://unixpapa.com/js/dyna1.js'); 
if(!document.getElementById('chr_js')) 
html_doc.appendChild(_js);

外部Javascript包含以下代码:

function lfunc(){
  alert('RUNNING loaded function');
}
alert('LAST LINE of script');

当我在选项卡中加载页面时,会出现“最后一行脚本”消息,表明脚本标记已正确插入DOM中。

我的扩展程序还有按钮(即browser_action)。现在,我希望此按钮在单击时调用上面定义的 lfunc()。不幸的是,我的代码根本无效

我在 background.html 页面中使用以下代码来处理我的按钮的onClick事件:

<script>
chrome.browserAction.onClicked.addListener(function(tab) {
  chrome.tabs.executeScript(null, 
    {code: "try {lfunc()} catch (e) {alert(e);}"});
  }); // it should call lfunc()
</script>

manifest.json 文件中的权限为:

"permissions": [
"tabs", "http://*/*", "https://*/*"  ]

我没有收到“ RUNNING loaded function ”消息,而是收到错误消息“ ReferenceError:lfunc未定义”。

我做错了什么?

3 个答案:

答案 0 :(得分:9)

您可以执行外部JS文件(通过将其注入DOM(扩展中的document))。外部JS文件也可以访问本地DOM。

这两者之间的沟通是不可能的:

  • 扩展程序无法访问用户添加的Javascript(非原生):
    扩展程序的JS无法访问页面的jQuery对象,但它可以访问其document.body
  • 用户添加的Javascript(页面的JS或您添加的外部JS)无权访问扩展名:
    在该页面中,您无法访问chrome API,如书签,标签,浏览器操作等。

出于安全原因,这是非常有意义的。

我所说的(sendRequestonRequest)是“内容脚本”和扩展脚本/背景页面之间的通信。在您的情况下无关紧要=)抱歉。

回答

  

&GT;我无法从扩展中调用外部JS文件中的特定函数,因为两者之间缺乏通信功能

没错。

  

&GT;我所能做的就是让我的扩展将外部JS文件注入DOM。这将执行外部JS文件中要执行的任何内容

没错。 ext JS可以包含立即动作和定时器等,就像正常加载的JS(在网页本身中)一样。

  

&GT;扩展中的代码启动粒度是在外部JS级别,而不是在JS功能级别

JS function level你是什么意思?扩展JS?

<强> PS
chrome.tabs.executeScript并不像你想象的那么酷。基本上它的作用是在页面的上下文中执行脚本(如content_scripts)。但是,它与content_scripts具有相同的限制:它可以达到DOM和本机JS功能,而不是用户添加JS。一个例子:

// Inside a `background_page`:
chrome.tabs.executeScript(null, {
    "code": "document.body.removeChild(document.body.firstChild);"
});

这很有效,因为只需要访问页面(总是存在的)DOM。以下内容不起作用(假设jQuery包含在网页本身中):

// Still inside a `background_page`:
chrome.tabs.executeScript(null, {
    "code": "jQuery('input').remove();"
});

这不起作用,因为jQuery是一个外部的,非本地的,用户添加的JS对象,扩展程序无法访问(background_pagecontent_scripts)。 /> 我真的不明白这个最后限制的原因,但它完全是关于Chrome中的沙盒和安全性=)我认为这是一件好事......

<强>顺便说一句
我认为你的问题的解决方案很简单......你可以让browser_action将外部JS注入到页面的DOM中。那就够了吧?外部JS包含逻辑AND实际函数调用。更好的解决方案,因为外部JS只在按下/触发browser_action(按钮)时加载。一个非常小的缺点:非常短暂的延迟(=在推送browser_action后下载外部JS)。

我可能再次建议:将所有扩展JS放入扩展中。这将允许脱机功能,并且永远不需要(另一方)连接到第三方服务器。

答案 1 :(得分:1)

alert('It doesn't work');替换为alert(e);

这可以让您更好地了解错误是什么。请发布错误。

答案 2 :(得分:1)

我需要调用其中一个页面脚本中的函数...

location = 'javascript:callToTheFunction(param,param,..)' did it.  

我正在谈论内容