Google chrome extension 使用Chrome内容脚本以编程方式将代码插入汇流页面

Google chrome extension 使用Chrome内容脚本以编程方式将代码插入汇流页面,google-chrome-extension,confluence,content-script,Google Chrome Extension,Confluence,Content Script,我正在尝试开发一个Chrome扩展,以使用该扩展在新选项卡中打开存储在Confluence中的Office文档 在“查看页面附件”屏幕中,有一个用于Office文件附件的“在Office中编辑”链接。该链接有一个单击事件,该事件创建用于打开文档的URLLauncher的新实例。Chrome不支持此功能,因此我想将自己的URLLauncher原型添加到网页中,使其正常工作 简而言之,这是我的想法: 创建一个带有内容脚本的Chrome扩展,该脚本将URLLauncher原型注入“查看页面附件”页面(

我正在尝试开发一个Chrome扩展,以使用该扩展在新选项卡中打开存储在Confluence中的Office文档

在“查看页面附件”屏幕中,有一个用于Office文件附件的“在Office中编辑”链接。该链接有一个单击事件,该事件创建用于打开文档的
URLLauncher
的新实例。Chrome不支持此功能,因此我想将自己的
URLLauncher
原型添加到网页中,使其正常工作

简而言之,这是我的想法:

  • 创建一个带有内容脚本的Chrome扩展,该脚本将
    URLLauncher
    原型注入“查看页面附件”页面(我不知道这是否是正确的方法,因此我愿意接受建议)
  • 当用户单击“在Office中编辑”链接时,
    URLLauncher.open
    方法通过调用IE选项卡扩展名在新选项卡中打开文件附件
  • 我能看到“你好!”每次我加载网页时都会发出警报,这确认正在注入content.js。但是,网页中没有
    URLLauncher
    。我认为这是因为内容脚本的全局
    window
    对象不同于页面/扩展的全局名称空间(即
    window.URLLauncher
    未定义)。如何重新组织代码以克服此障碍

    这些是我的文件:

    manifest.json

    {
       "manifest_version": 2,
       "background": {
          "scripts": [
             "background.js"
          ]
       },
       "content_scripts": [ {
          "js": [ "content.js" ],
          "matches": [ "<all_urls>" ]
       } ],
       "description": "This is a test extension",
       "permissions": [
          "tabs", "http://*/*", "https://*/*"
       ],
       "name": "Test extension",
       "version": "1.0.0"
    }
    
    {
       "manifest_version": 2,
       "content_scripts": [ {
          "js": [ "content.js" ],
          "matches": [ "<all_urls>" ]
       } ],
       "web_accessible_resources": [ "script.js" ],
       "description": "This is a test extension",
       "permissions": [
          "tabs", "http://*/*", "https://*/*"
       ],
       "name": "Test extension",
       "version": "1.0.0",
       "externally_connectable": {
          "ids": ["*"],
          "matches": ["*://*.hostname.com/*"]
       }
    }
    
    content.js

    chrome.tabs.executeScript(null, { 
       code: "document.body.appendChild(document.createElement('script')).src='" + 
       chrome.extension.getURL("content.js") + "';" 
    }, null);
    
    chrome.runtime.onMessage.addListener(
       function(request, sender, sendResponse) {
          console.log(sender.tab ?
                "from a content script:" + sender.tab.url :
                "from the extension");
          if (request.id == "doUrlLaunch") {        
             chrome.tabs.create({ url: request.nUrl, selected: true });
             sendResponse({result: "goodbye"});
          }
       }
    );
    
    var prefixUrl = 'chrome-extension://hehijbfgiekmjfkfjpbkbammjbdenadd/iecontainer.html#url=';
    alert('Hi there!');
    function URLLauncher() {
    
    }
    
    URLLauncher.prototype = {  
       open : function(urlStr) {
          var newUrl = prefixUrl + 'https://host.com' + encodeURI(urlStr);
          chrome.runtime.sendMessage({id: "doUrlLaunch", nUrl: newUrl}, function(response) {
          });
       }
    }
    
    var s = document.createElement('script');
    s.src = chrome.extension.getURL("script.js");
    s.onload = function() {
        this.parentNode.removeChild(this);
    };
    (document.head||document.documentElement).appendChild(s);
    
    chrome.runtime.onMessage.addListener(
    //Unreachable code!
       function(request, sender, sendResponse) {
          console.log(sender.tab ?
                "from a content script:" + sender.tab.url :
                "from the extension");
          if (request.id == "doUrlLaunch") {        
             chrome.tabs.create({ url: request.nUrl, selected: true });
             sendResponse({result: "goodbye"});
          }
       }
    );
    
    var prefixUrl = 'chrome-extension://hehijbfgiekmjfkfjpbkbammjbdenadd/iecontainer.html#url=';
    function URLLauncher() {
    
    }
    
    URLLauncher.prototype = {  
       open : function(urlStr) {
          var newUrl = prefixUrl + 'https://hostname.com' + encodeURI(urlStr);
          chrome.runtime.sendMessage({id: "doUrlLaunch", nUrl: newUrl}, function(response) {
              if (!response.success)
                  console.log('Something went wrong...');
          });
       }
    }
    
    提前谢谢

    更新1

    我按照和给出的说明编辑了文件(“消息传递”);现在代码被注入页面本身,但仍然存在一个主要问题。实际的JS代码向内容脚本发送一条消息,但是侦听器没有捕捉到该消息,因此不会创建新选项卡,回调函数也不会收到响应;我收到的错误消息:事件处理程序中的错误(未知):TypeError:无法读取未定义的属性“success”

    以下是更新的文件:

    manifest.json

    {
       "manifest_version": 2,
       "background": {
          "scripts": [
             "background.js"
          ]
       },
       "content_scripts": [ {
          "js": [ "content.js" ],
          "matches": [ "<all_urls>" ]
       } ],
       "description": "This is a test extension",
       "permissions": [
          "tabs", "http://*/*", "https://*/*"
       ],
       "name": "Test extension",
       "version": "1.0.0"
    }
    
    {
       "manifest_version": 2,
       "content_scripts": [ {
          "js": [ "content.js" ],
          "matches": [ "<all_urls>" ]
       } ],
       "web_accessible_resources": [ "script.js" ],
       "description": "This is a test extension",
       "permissions": [
          "tabs", "http://*/*", "https://*/*"
       ],
       "name": "Test extension",
       "version": "1.0.0",
       "externally_connectable": {
          "ids": ["*"],
          "matches": ["*://*.hostname.com/*"]
       }
    }
    
    script.js

    chrome.tabs.executeScript(null, { 
       code: "document.body.appendChild(document.createElement('script')).src='" + 
       chrome.extension.getURL("content.js") + "';" 
    }, null);
    
    chrome.runtime.onMessage.addListener(
       function(request, sender, sendResponse) {
          console.log(sender.tab ?
                "from a content script:" + sender.tab.url :
                "from the extension");
          if (request.id == "doUrlLaunch") {        
             chrome.tabs.create({ url: request.nUrl, selected: true });
             sendResponse({result: "goodbye"});
          }
       }
    );
    
    var prefixUrl = 'chrome-extension://hehijbfgiekmjfkfjpbkbammjbdenadd/iecontainer.html#url=';
    alert('Hi there!');
    function URLLauncher() {
    
    }
    
    URLLauncher.prototype = {  
       open : function(urlStr) {
          var newUrl = prefixUrl + 'https://host.com' + encodeURI(urlStr);
          chrome.runtime.sendMessage({id: "doUrlLaunch", nUrl: newUrl}, function(response) {
          });
       }
    }
    
    var s = document.createElement('script');
    s.src = chrome.extension.getURL("script.js");
    s.onload = function() {
        this.parentNode.removeChild(this);
    };
    (document.head||document.documentElement).appendChild(s);
    
    chrome.runtime.onMessage.addListener(
    //Unreachable code!
       function(request, sender, sendResponse) {
          console.log(sender.tab ?
                "from a content script:" + sender.tab.url :
                "from the extension");
          if (request.id == "doUrlLaunch") {        
             chrome.tabs.create({ url: request.nUrl, selected: true });
             sendResponse({result: "goodbye"});
          }
       }
    );
    
    var prefixUrl = 'chrome-extension://hehijbfgiekmjfkfjpbkbammjbdenadd/iecontainer.html#url=';
    function URLLauncher() {
    
    }
    
    URLLauncher.prototype = {  
       open : function(urlStr) {
          var newUrl = prefixUrl + 'https://hostname.com' + encodeURI(urlStr);
          chrome.runtime.sendMessage({id: "doUrlLaunch", nUrl: newUrl}, function(response) {
              if (!response.success)
                  console.log('Something went wrong...');
          });
       }
    }
    

    不确定您是否仍然对答案感兴趣,但在您编辑的文件中,您的问题在于您的听众所在的位置

  • chrome.runtime.sendMessage
    未到达内容脚本;它用于扩展页面。传递给内容脚本的消息通过
    chrome.tabs.sendMessage
    工作,但这与此任务无关

  • 内容脚本无法调用
    chrome.tabs
    ,因为它们没有所需的API访问权限

  • 一个解决方案是调用后台脚本,该脚本可以接收这些消息并调用所需的API

    因此,您需要第三个脚本,将此代码从
    content.js
    中取出:

    // background.js
    chrome.runtime.onMessage.addListener(
       function(request, sender, sendResponse) {
          console.log(sender.tab ?
                "from a content script:" + sender.tab.url :
                "from the extension");
          if (request.id == "doUrlLaunch") {        
             chrome.tabs.create({ url: request.nUrl, selected: true });
             sendResponse({result: "goodbye"});
          }
       }
    );    
    
    并修改您的清单:

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

    可能重复感谢您的帮助,Rob W。我更新了我的代码,但是注入的代码似乎无法将消息发送到内容脚本,正如我在上面详细解释的那样。我很感激你的见解。注入脚本的行为就像它们来自注入的页面一样。此类脚本不能使用任何Chrome扩展API。要与后台脚本“对话”,用户首先需要向内容脚本发送消息,内容脚本再向后台页面发送消息。有关将消息从注入脚本发送到后台的完整示例,请参阅。有关注入脚本和内容脚本之间通信的另一个示例,请参阅。