chrome extension无法使用内容脚本和其他方式从google加载外部javascript

chrome extension无法使用内容脚本和其他方式从google加载外部javascript,javascript,google-chrome-extension,Javascript,Google Chrome Extension,我正在编写一个chrome扩展,它将为facebook中的特定文本框启用音译 我已使用脚本选项卡加载background.html 下面是我在内容脚本中使用的代码 我尝试使用ajax和通用方式加载 当我检查时,它说谷歌未定义 /* $.ajax({ url: "https://www.google.com/jsapi", dataType: "script", }); */ var script = document.createElement("script"); script.

我正在编写一个chrome扩展,它将为facebook中的特定文本框启用音译

我已使用脚本选项卡加载background.html

下面是我在内容脚本中使用的代码 我尝试使用ajax和通用方式加载

当我检查时,它说谷歌未定义

/*
$.ajax({
  url: "https://www.google.com/jsapi",
  dataType: "script",

});
*/

var script = document.createElement("script"); 
script.setAttribute('type','text/javascript'); 
script.setAttribute('src','https://www.google.com/jsapi?'+(new Date()).getTime()); 
document.body.appendChild(script);

$(document).ready(function()
{
    alert(google)
    if(window.location.href.indexOf('facebook.com'))
        yes_it_is_facebook();
})



function yes_it_is_facebook()
{
//  document.getElementsByName('xhpc_message_text')[0].id = 'facebook_tamil_writer_textarea';

//  alert(document.getElementsByName('xhpc_message').length)

    google.load("elements", "1", { packages: "transliteration" });  
    google.setOnLoadCallback(onLoad);   
}

function onLoad()
{
    var options = {
                sourceLanguage:
                    google.elements.transliteration.LanguageCode.ENGLISH,
                destinationLanguage:
                    [google.elements.transliteration.LanguageCode.HINDI],
                shortcutKey: 'ctrl+g',
                transliterationEnabled: true
            };

    var control = new google.elements.transliteration.TransliterationControl(options);  
    control.makeTransliteratable(['facebook_tamil_writer_textarea']);   
}
在manifest.json内容脚本数组中

  "content_scripts": [
    {
        "matches": ["<all_urls>"],
      "js": ["js/jquery-1.7.2.min.js", "js/myscript.js", "https://www.google.com/jsapi"]
    }
  ],
“内容脚本”:[
{
“匹配项”:[”表示内容
剧本

这是我的manifest.json

{
  "name": "Facebook Tamil Writer",
  "version": "1.0",
  "description": "Facebook Tamil Writer",
  "browser_action": {
    "default_icon": "images/stick-man1.gif",
    "popup":"popup.html"
  },

  "background_page": "background.html",

  "content_scripts": [
    {
        "matches": ["<all_urls>"],
      "js": ["js/jquery-1.7.2.min.js", "js/myscript.js", "https://www.google.com/jsapi"]
    }
  ],

  "permissions": [
    "http://*/*",
    "https://*/*",
    "contextMenus",
    "tabs"
  ]
}
{
“姓名”:“Facebook泰米尔作家”,
“版本”:“1.0”,
“描述”:“Facebook泰米尔作家”,
“浏览器操作”:{
“默认图标”:“images/stick-man1.gif”,
“popup”:“popup.html”
},
“背景页面”:“background.html”,
“内容脚本”:[
{
“匹配项”:[“为了您的理解,我也测试过删除它

那么,我如何将javascript加载到文档上下文中。也就是加载网页时……这里我专门为facebook加载。我仍然必须纠正indexof条件,因为它没有给出正确的结果,但这不是我问题的上下文的问题


因此,请建议我。

我似乎找不到任何与此相关的文档,但我认为您不能在
content\u scripts
选项中提及
http://
路径。可能的解决方法是:

$('head').append("<script type='text/javascript' src='http://google.com/jsapi'>");
$('head')。追加(“”);
或者通过ajax请求加载它,正如您在代码中注释的那样

其次,必须先加载
google.com/jsapi
,然后才能在脚本中使用它。在清单中,首先加载脚本,然后再加载
google.com/jsapi

友好的建议: 默认情况下,jQuery通过在url末尾附加时间戳来禁止缓存。由于您尝试加载的脚本不太可能在短时间内更改,因此您可以传递
cache:false
作为节省加载时间的选项。有关详细信息,请查看。
更好的是,您可以将脚本与包捆绑在一起,这样就不会有与扩展相关联的ajax请求,这将提高扩展的速度。

google.load的最大问题之一是,它无法在页面完全加载后正确加载资源,因为要插入脚本/样式的API要解决此问题,必须修补两种方法:

(function(g) {
    var loader_d = g.loader.d,
        setOnLoadCallback = g.setOnLoadCallback;
    // Force not to use document.write when the document is loaded
    g.loader.d = g.loader.writeLoadTag = function(a, b) {
       loader_d(a, b, document.readyState === 'complete');
    };
    // Executes functions directly when page has loaded
    g.setOnLoadCallback = function(a_listener, b) {
        if (b || document.readyState !== 'complete') {
            setOnLoadCallback(a_listener, b);
        } else {
            // When the API is not loaded yet, a TypeError with google.
            //  will be thrown. Not a ReferenceError, because google.* is defined
            // Retry max *c* times.
            var c = 5;
            b = function() {
                try {
                    a_listener();
                } catch (e) {
                   if (e instanceof TypeError && (''+e).indexOf('google.')!=-1) {
                       if (c--) setTimeout(b, 2000);
                   }
                }
            };
            b();
        }
    };
})(google);
现在,问题2:内容脚本运行在:全局命名空间的任何属性,
窗口
,都是不可访问的。因此,任何注入的API对内容脚本都是不可见的


要解决此问题,请参阅以下堆栈溢出答案:。

这可能有助于理解Chrome的安全策略

在中,有人说,如果您将脚本标记附加到页面(而不是弹出窗口或内容脚本),它将加载到页面上下文中,而不是扩展。并且扩展中的脚本无法与页面的脚本对话。如果您查看页面脚本,您将在那里看到它,但不会在扩展脚本下看到它

我在尝试注入GoogleAPI脚本时发现了这一点

script = document.createElement('script');
script.src = "https://apis.google.com/js/client.js?onload=init";
(document.head||document.documentElement).appendChild(script);
init函数是在我的内容脚本中定义的。但是GoolgeAPI脚本是作为页面脚本加载的。所以如果我这样做的话

var script = document.createElement('script');

script.innerText = "function init(){ alert('hi'); }";
(document.head||document.documentElement).appendChild(script);

script = document.createElement('script');
script.src = "https://apis.google.com/js/client.js?onload=init";
(document.head||document.documentElement).appendChild(script);

调用了注入的init函数,我看到了警报“hi”。我不确定这是否有帮助,但我想我会为正在加载Google API的其他人记下它。如果我想办法实际加载它,我会更新这个答案。

很好……但正如我所说的,Google.com/jsapi在manifest.json中不起作用……它显示了error…请仔细研究我的问题。建议除外。@juzerali此错误不是由动态加载API的不同方式引起的。事实上,“正确”加载Google的JS API的方法是直接将其放在
中。但在很多情况下这是不可能的。用另一种方式加载API会生成。嗯,我似乎做不到:*“JS”:[“./foo.JS”]**顺便说一句,“将此代码段放在哪里?”-->在使用
google.load
方法之前,您需要将内容脚本中的消息发送到后台/事件页面,以便执行
chrome.tabs.executeScript()
在页面范围内插入外部脚本。