24

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

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

问题是 Chrome 的内容脚本 API 只允许注入 javascript。这意味着,要注入复杂的 HTML 布局,我需要完全用 JS 对象来编写它,这很长,难以维护,而且绝对不适合设计人员。

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

4

3 回答 3

40

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

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

  2. 将 HTML 使用的任何*.css*.js文件也放在扩展文件夹中。

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

    "web_accessible_resources": ["Embedded_Hello_world.htm"]
    


  4. 不要在 HTML 文件中使用任何内联或外部服务器 javascript。这避免内容安全策略(CSP)的问题。

  5. 这个问题不涉及与页面/iframe 的通信,但如果你想这样做,它会涉及更多。在此处搜索 SO;它被覆盖了很多次。


例子:

您可以通过以下方式看到这一点:

  1. 创建一个新的扩展文件夹。
  2. 将jQuery下载到其中。
  3. 创建如下指定的 5 个文件。
  4. 加载解压后的扩展(您可以在此答案中看到类似的步骤。)
  5. 在 Chrome 中重新加载此页面;您将看到嵌入在顶部的“Hello World”页面。

在扩展文件夹中创建这些文件:

清单.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>');
}
于 2013-04-08T10:17:32.863 回答
5

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

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();
于 2017-01-17T08:59:40.077 回答
3

我有同样的问题,我的扩展严重依赖脚本模板

这是我所做的:

  • 创建templates.html以将脚本模板存储在
  • 添加templates.htmlweb_accessible_resources上述答案中的内容^^
  • templates.html使用content.jsxhr访问并使用 jQuery 解析

清单.json

"web_accessible_resources": ["templates.html"]

模板.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>

内容.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>
});
于 2016-05-10T00:01:27.340 回答