草庐IT

javascript - chrome 扩展中内容脚本的未定义响应

coder 2024-07-27 原文

我无法从我的内容脚本中获得响应以显示在我的 popup.html 中。当此代码运行并单击查找按钮时,“Hello from response!”打印,但变量 response 打印为未定义。最终目标是将当前选项卡的 DOM 放入我的脚本文件中,以便我可以解析它。我正在向内容脚本使用单一时间消息来获取 DOM,但它没有被返回并且显示为未定义。我正在寻找任何可能的帮助。谢谢。

popup.html:

<!DOCTYPE html>
<html>
    <body>
        <head>
        <script src="script.js"></script>
        </head>

        <form >
            Find: <input id="find" type="text"> </input>
        </form>
        <button id="find_button"> Find </button>
    </body>
</html>

list .json:

{
    "name": "Enhanced Find",
    "version": "1.0",
    "manifest_version": 2,
    "description": "Ctrl+F, but better",
    "browser_action": {
        "default_icon": "icon.png", 
        "default_popup": "popup.html"
    },
    "permissions": [
        "tabs",
        "*://*/*"
    ],

    "background":{
        "scripts": ["script.js"],
        "persistent": true
    },

    "content_scripts":[
        {
            "matches": ["http://*/*", "https://*/*"],
            "js": ["content_script.js"],
            "run_at": "document_end"
        }
   ]
}

脚本.js:

var bkg = chrome.extension.getBackgroundPage();


function eventHandler(){
    var input = document.getElementById("find");
    var text = input.value;
    chrome.tabs.query({active: true, currentWindow: true}, function(tabs){
        var tab = tabs[0];
        var url = tab.url;
        chrome.tabs.sendMessage(tab.id, {method: "getDocuments"}, function(response){
            bkg.console.log("Hello from response!");
            bkg.console.log(response);
        });

    });
}

content_script.js:

var bkg = chrome.extension.getBackgroundPage();

chrome.runtime.onMessage.addListener(function(request, sender, sendResponse){
    if(request.method == "getDOM"){
        sendResponse({data : bkg.document});
    }else{
        sendResponse({});
    }
});

最佳答案

你的代码有很多问题(见我上面的评论)。


首先是一些建议/注意事项:

  • 不要将您的内容脚本插入到所有 网页中。 <强> Inject programmatically 并且仅当用户想要搜索时。

  • 最好直接在内容脚本中进行“搜索”,这样您可以直接访问 DOM 并对其进行操作(例如突出显示搜索结果等)。如果您采用这种方法,您可能需要调整您的权限,但始终尽量将它们保持在最低限度(例如,不要在 activeTab 就足够的地方使用 tabs 等).

  • 请记住,一旦弹出窗口关闭/隐藏(例如,一个选项卡获得焦点),所有在弹出窗口上下文中执行的 JS 都将中止。

  • 如果您想要某种持久性(甚至是临时性的),例如记住最近的结果或上一个搜索词,您可以使用类似 chrome.storage 的东西 localStorage .


最后,来 self 的扩展程序演示版本的示例代码:

扩展文件组织:

          extension-root-directory/
           |
           |_____fg/
           |      |_____content.js
           |
           |_____popup/
           |      |_____popup.html
           |      |_____popup.js
           |
           |_____manifest.json

list .json:

{
    "manifest_version": 2,
    "name":    "Test Extension",
    "version": "0.0",
    "offline_enabled": true,

    "content_scripts": [
        {
            "matches": [
                "http://*/*",
                "https://*/*"
            ],
            "js":     ["fg/content.js"],
            "run_at": "document_end",
        }
    ],

    "browser_action": {
        "default_title": "Test Extension",
        "default_popup": "popup/popup.html"
    }
}

content.js:

// Listen for message...
chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
    // If the request asks for the DOM content...
    if (request.method && (request.method === "getDOM")) {
        // ...send back the content of the <html> element
        // (Note: You can't send back the current '#document',
        //  because it is recognised as a circular object and 
        //  cannot be converted to a JSON string.)
        var html = document.all[0];
        sendResponse({ "htmlContent": html.innerHTML });
    }
});

popup.html:

<!DOCTYPE html>
<html>
    <head>
        <script type="text/javascript" src="popup.js"></script>
    </head>
    <body>
        Search:
        <input type="text" id="search" />
        <input type="button" id="searchBtn" value=" Find "
               style="width:100%;" />
    </body>
</html>

popup.js:

window.addEventListener("DOMContentLoaded", function() {
    var inp = document.getElementById("search");
    var btn = document.getElementById("searchBtn");

    btn.addEventListener("click", function() {
        var searchTerm = inp.value;
        if (!inp.value) {
            alert("Please, enter a term to search for !");
        } else {
            // Get the active tab
            chrome.tabs.query({
                active: true,
                currentWindow: true
            }, function(tabs) {
                // If there is an active tab...
                if (tabs.length > 0) {
                    // ...send a message requesting the DOM...
                    chrome.tabs.sendMessage(tabs[0].id, {
                        method: "getDOM"
                    }, function(response) {
                        if (chrome.runtime.lastError) {
                            // An error occurred :(
                            console.log("ERROR: ", chrome.runtime.lastError);
                        } else {
                            // Do something useful with the HTML content
                            console.log([
                                "<html>", 
                                response.htmlContent, 
                                "</html>"
                            ].join("\n"));
                        }
                    });
                }
            });
        }
    });
});

关于javascript - chrome 扩展中内容脚本的未定义响应,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19641042/

有关javascript - chrome 扩展中内容脚本的未定义响应的更多相关文章

  1. ruby - Facter::Util::Uptime:Module 的未定义方法 get_uptime (NoMethodError) - 2

    我正在尝试设置一个puppet节点,但ruby​​gems似乎不正常。如果我通过它自己的二进制文件(/usr/lib/ruby/gems/1.8/gems/facter-1.5.8/bin/facter)在cli上运行facter,它工作正常,但如果我通过由ruby​​gems(/usr/bin/facter)安装的二进制文件,它抛出:/usr/lib/ruby/1.8/facter/uptime.rb:11:undefinedmethod`get_uptime'forFacter::Util::Uptime:Module(NoMethodError)from/usr/lib/ruby

  2. ruby - 如何将脚本文件的末尾读取为数据文件(Perl 或任何其他语言) - 2

    我正在寻找执行以下操作的正确语法(在Perl、Shell或Ruby中):#variabletoaccessthedatalinesappendedasafileEND_OF_SCRIPT_MARKERrawdatastartshereanditcontinues. 最佳答案 Perl用__DATA__做这个:#!/usr/bin/perlusestrict;usewarnings;while(){print;}__DATA__Texttoprintgoeshere 关于ruby-如何将脚

  3. ruby - 将数组的内容转换为 int - 2

    我需要读入一个包含数字列表的文件。此代码读取文件并将其放入二维数组中。现在我需要获取数组中所有数字的平均值,但我需要将数组的内容更改为int。有什么想法可以将to_i方法放在哪里吗?ClassTerraindefinitializefile_name@input=IO.readlines(file_name)#readinfile@size=@input[0].to_i@land=[@size]x=1whilex 最佳答案 只需将数组映射为整数:@land边注如果你想得到一条线的平均值,你可以这样做:values=@input[x]

  4. ruby-on-rails - Rails 3.2.1 中 ActionMailer 中的未定义方法 'default_content_type=' - 2

    我在我的项目中添加了一个系统来重置用户密码并通过电子邮件将密码发送给他,以防他忘记密码。昨天它运行良好(当我实现它时)。当我今天尝试启动服务器时,出现以下错误。=>BootingWEBrick=>Rails3.2.1applicationstartingindevelopmentonhttp://0.0.0.0:3000=>Callwith-dtodetach=>Ctrl-CtoshutdownserverExiting/Users/vinayshenoy/.rvm/gems/ruby-1.9.3-p0/gems/actionmailer-3.2.1/lib/action_mailer

  5. ruby - 使用 C 扩展开发 ruby​​gem 时,如何使用 Rspec 在本地进行测试? - 2

    我正在编写一个包含C扩展的gem。通常当我写一个gem时,我会遵循TDD的过程,我会写一个失败的规范,然后处理代码直到它通过,等等......在“ext/mygem/mygem.c”中我的C扩展和在gemspec的“扩展”中配置的有效extconf.rb,如何运行我的规范并仍然加载我的C扩展?当我更改C代码时,我需要采取哪些步骤来重新编译代码?这可能是个愚蠢的问题,但是从我的gem的开发源代码树中输入“bundleinstall”不会构建任何native扩展。当我手动运行rubyext/mygem/extconf.rb时,我确实得到了一个Makefile(在整个项目的根目录中),然后当

  6. ruby-on-rails - form_for 中不在模型中的自定义字段 - 2

    我想向我的Controller传递一个参数,它是一个简单的复选框,但我不知道如何在模型的form_for中引入它,这是我的观点:{:id=>'go_finance'}do|f|%>Transferirde:para:Entrada:"input",:placeholder=>"Quantofoiganho?"%>Saída:"output",:placeholder=>"Quantofoigasto?"%>Nota:我想做一个额外的复选框,但我该怎么做,模型中没有一个对象,而是一个要检查的对象,以便在Controller中创建一个ifelse,如果没有检查,请帮助我,非常感谢,谢谢

  7. ruby - 主要 :Object when running build from sublime 的未定义方法 `require_relative' - 2

    我已经从我的命令行中获得了一切,所以我可以运行rubymyfile并且它可以正常工作。但是当我尝试从sublime中运行它时,我得到了undefinedmethod`require_relative'formain:Object有人知道我的sublime设置中缺少什么吗?我正在使用OSX并安装了rvm。 最佳答案 或者,您可以只使用“require”,它应该可以正常工作。我认为“require_relative”仅适用于ruby​​1.9+ 关于ruby-主要:Objectwhenrun

  8. ruby-on-rails - 独立 ruby​​ 脚本的配置文件 - 2

    我有一个在Linux服务器上运行的ruby​​脚本。它不使用rails或任何东西。它基本上是一个命令行ruby​​脚本,可以像这样传递参数:./ruby_script.rbarg1arg2如何将参数抽象到配置文件(例如yaml文件或其他文件)中?您能否举例说明如何做到这一点?提前谢谢你。 最佳答案 首先,您可以运行一个写入YAML配置文件的独立脚本:require"yaml"File.write("path_to_yaml_file",[arg1,arg2].to_yaml)然后,在您的应用中阅读它:require"yaml"arg

  9. ruby-on-rails - 如何在我的 Rails 应用程序 View 中打印 ruby​​ 变量的内容? - 2

    我是一个Rails初学者,但我想从我的RailsView(html.haml文件)中查看Ruby变量的内容。我试图在ruby​​中打印出变量(认为它会在终端中出现),但没有得到任何结果。有什么建议吗?我知道Rails调试器,但更喜欢使用inspect来打印我的变量。 最佳答案 您可以在View中使用puts方法将信息输出到服务器控制台。您应该能够在View中的任何位置使用Haml执行以下操作:-puts@my_variable.inspect 关于ruby-on-rails-如何在我的R

  10. ruby - 在 Ruby 中有条件地定义函数 - 2

    我有一些代码在几个不同的位置之一运行:作为具有调试输出的命令行工具,作为不接受任何输出的更大程序的一部分,以及在Rails环境中。有时我需要根据代码的位置对代码进行细微的更改,我意识到以下样式似乎可行:print"Testingnestedfunctionsdefined\n"CLI=trueifCLIdeftest_printprint"CommandLineVersion\n"endelsedeftest_printprint"ReleaseVersion\n"endendtest_print()这导致:TestingnestedfunctionsdefinedCommandLin

随机推荐