使用Chrome内容脚本添加复杂的HTML

时间:2013-04-08 07:48:58

标签: javascript html5 google-chrome google-chrome-extension content-script

我正在使用Chrome扩展程序的内容脚本来创建添加到网页上的复杂显示。

我首先将它直接集成在一个网站上测试,但现在我需要把它放在一个扩展名中。

问题是Chrome的内容脚本API只允许注入javascript。这意味着,为了注入复杂的HTML布局,我需要用JS对象完全编写它,这些文件很难编写,难以维护并且绝对不是设计人员友好的。

我想知道是否有人知道或者能想出一个聪明的方法来获得更好的工作流程。

3 个答案:

答案 0 :(得分:30)

通过让您的内容脚本将其注入iframe来添加整个网页相对容易。请遵循以下准则:

  1. *.htm*.html个文件放在扩展程序的源文件夹中。

  2. 将HTML使用的所有*.css*.js个文件也放在扩展程序文件夹中。

  3. 将HTML文件声明为资源。 EG:

    "web_accessible_resources": ["Embedded_Hello_world.htm"]
    


  4. 请勿在HTML文件中使用任何 内嵌 或外部服务器javascript。这避免了the Content Security Policy (CSP)

  5. 的问题
  6. 此问题不包括与页面/ iframe的通信,但如果您想这样做,则会涉及更多内容。在这里搜索SO;它被覆盖了很多次。


  7. 实施例

    您可以通过以下方式查看此操作:

    1. 创建新的扩展文件夹。
    2. jQuery下载到其中。
    3. 按照以下规定创建5个文件。
    4. 加载解压缩的扩展程序(您可以在this answer中看到类似的步骤。)
    5. 在Chrome中重新加载此页面;你会看到嵌入在顶部的“Hello World”页面。
    6. 在扩展文件夹中创建这些文件:

      <强>的manifest.json:

      {
          "manifest_version":         2,
          "content_scripts":          [ {
              "js":       [ "iframeInjector.js" ],
              "matches":  [   "https://stackoverflow.com/questions/*"
              ]
          } ],
          "description":              "Inject a complete, premade web page",
          "name":                     "Inject whole web page",
          "version":                  "1",
          "web_accessible_resources": ["Embedded_Hello_world.htm"]
      }
      


      iframeInjector.js:

      var iFrame  = document.createElement ("iframe");
      iFrame.src  = chrome.extension.getURL ("Embedded_Hello_world.htm");
      
      document.body.insertBefore (iFrame, document.body.firstChild);
      


      Embedded_Hello_world.htm:

      <!DOCTYPE html>
      <html><head>
          <title>Embedded Hello World</title>
          <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
      
          <link href="HelloWorld.css" rel="stylesheet" type="text/css">
      
          <script type="text/javascript" src="jquery.min.js"></script>
          <script type="text/javascript" src="HelloWorld.js"></script>
      </head><body>
      <p>Hello World!</p>
      </body></html>
      


      HelloWorld.css:

      body {
          color:              red;
          background-color:   lightgreen;
      }
      


      HelloWorld.js:

      $(document).ready (jQueryMain);
      
      function jQueryMain () {
          $("body").append ('<p>Added by jQuery</p>');
      }
      

答案 1 :(得分:1)

我遇到了同样的问题,我的扩展很大程度上依赖于script templates

这就是我的所作所为:

  • 创建templates.html以在
  • 中存储脚本模板
  • templates.html添加到web_accessible_resources,如上面的答案^^
  • 使用xhr从templates.html访问content.js并使用jQuery
  • 进行解析

的manifest.json

"web_accessible_resources": ["templates.html"]

templates.html

<script id="template1" type="text/template">
    <div class="template1">template1</div>
</script>
<script id="template2" type="text/template">
    <div class="template2">template2</div>
</script>

content.js

function getTemplates(){
    return new Promise(function(resolve){
        $.ajax({
            url: chrome.extension.getURL('/templates.html'),
            success: function(data) {
                var $templates = $('<div></div>').append($.parseHTML(data)).find('script'),
                    templates = {};
                $templates.each(function(){
                    templates[this.id] = this.innerHTML;
                });
                return resolve(templates);
            }
        });
    });
}
getTemplates().then(function(templates){
    console.log(templates.template1); //<div class="template1">template1</div>
});

答案 2 :(得分:1)

这可能更好,没有外部库,也没有iframe。与iautomation解决方案几乎相同。

var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
        var div = document.createElement('div');
        div.innerHTML = this.responseText;
        document.body.insertBefore(div, document.body.firstChild);
    } else {
        console.log('files not found');
    }
};
xhttp.open("GET", chrome.extension.getURL("/content.htm"), true);
xhttp.send();