Javascript 向新打开的窗口注入内容\u脚本

Javascript 向新打开的窗口注入内容\u脚本,javascript,google-chrome-extension,Javascript,Google Chrome Extension,我正在开发一个个人使用的扩展,它只会自动在网站a上重复一些操作。 这就是我希望使用Chrome extension实现自动化的基本流程: 触发一个按钮点击事件 将打开一个新的弹出窗口(由网站A打开) 在打开的窗口中填写表格 单击提交按钮 目前,我的扩展正在为我想要自动化的特定网站使用Chrome的pageAction manifest.json { "manifest_version": 2, "name": "Automater", "version": "0.0.1",

我正在开发一个个人使用的扩展,它只会自动在网站a上重复一些操作。 这就是我希望使用Chrome extension实现自动化的基本流程:

  • 触发一个按钮点击事件
  • 将打开一个新的弹出窗口(由网站A打开)
  • 在打开的窗口中填写表格
  • 单击提交按钮
  • 目前,我的扩展正在为我想要自动化的特定网站使用Chrome的
    pageAction

    manifest.json

    {
      "manifest_version": 2,
    
      "name": "Automater",  
      "version": "0.0.1",
    
      "page_action": {
        "default_title": "Click here!",
        "default_icon": "icon.png"
      },
      "content_scripts": [
        {
          "matches": [
            "https://www.website.com/*"
          ],
          "js": ["jquery-3.2.1.min.js", "content.js"],
          "run_at": "document_end"
        }
      ],
      "background": {
        "scripts": ["background.js"],
        "persistent": false
      },
      "permissions": [
        "activeTab",
        "tabs",
        "declarativeContent",
        "storage"
      ]
    }
    
    chrome.pageAction.onClicked.addListener(function(tab) {
      chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
        var activeTab = tabs[0];
        chrome.tabs.sendMessage(
          activeTab.id,
          { 'message': 'click_btn' }
        );
      });
    });
    
    chrome.runtime.onInstalled.addListener(function() {
      chrome.declarativeContent.onPageChanged.removeRules(
          undefined, function() {
        chrome.declarativeContent.onPageChanged.addRules([
          {
            conditions: [
              new chrome.declarativeContent.PageStateMatcher({
                pageUrl: {
                  urlContains: 'www.website.com',
                  schemes: ['https']
                },
              })
            ],
            actions: [ new chrome.declarativeContent.ShowPageAction() ]
          }
        ]);
      });
    });
    
    chrome.windows.onCreated.addListener(function(newWindow) {
      chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
        var activeTab = tabs[0];
        chrome.tabs.sendMessage(
          activeTab.id,
          { 'message': 'fill_form' }
        );
      });
    });
    
    chrome.runtime.onMessage.addListener(
      function(request, sender, sendResponse) {
        if( request.message === 'btn_clicked' ) {
          citationsSize = request.citationsSize;
        }
      }
    );
    
    chrome.runtime.onMessage.addListener(
      function(request, sender, sendResponse) {
        switch(request.message) {
          case 'click_btn':
            $("#btn_id").click();
    
            chrome.runtime.sendMessage({
              "message": 'btn_clicked'          
            });
            break;
          case 'fill_form':
            console.log('start filling');        
        };
      }
    );
    
    background.js

    {
      "manifest_version": 2,
    
      "name": "Automater",  
      "version": "0.0.1",
    
      "page_action": {
        "default_title": "Click here!",
        "default_icon": "icon.png"
      },
      "content_scripts": [
        {
          "matches": [
            "https://www.website.com/*"
          ],
          "js": ["jquery-3.2.1.min.js", "content.js"],
          "run_at": "document_end"
        }
      ],
      "background": {
        "scripts": ["background.js"],
        "persistent": false
      },
      "permissions": [
        "activeTab",
        "tabs",
        "declarativeContent",
        "storage"
      ]
    }
    
    chrome.pageAction.onClicked.addListener(function(tab) {
      chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
        var activeTab = tabs[0];
        chrome.tabs.sendMessage(
          activeTab.id,
          { 'message': 'click_btn' }
        );
      });
    });
    
    chrome.runtime.onInstalled.addListener(function() {
      chrome.declarativeContent.onPageChanged.removeRules(
          undefined, function() {
        chrome.declarativeContent.onPageChanged.addRules([
          {
            conditions: [
              new chrome.declarativeContent.PageStateMatcher({
                pageUrl: {
                  urlContains: 'www.website.com',
                  schemes: ['https']
                },
              })
            ],
            actions: [ new chrome.declarativeContent.ShowPageAction() ]
          }
        ]);
      });
    });
    
    chrome.windows.onCreated.addListener(function(newWindow) {
      chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
        var activeTab = tabs[0];
        chrome.tabs.sendMessage(
          activeTab.id,
          { 'message': 'fill_form' }
        );
      });
    });
    
    chrome.runtime.onMessage.addListener(
      function(request, sender, sendResponse) {
        if( request.message === 'btn_clicked' ) {
          citationsSize = request.citationsSize;
        }
      }
    );
    
    chrome.runtime.onMessage.addListener(
      function(request, sender, sendResponse) {
        switch(request.message) {
          case 'click_btn':
            $("#btn_id").click();
    
            chrome.runtime.sendMessage({
              "message": 'btn_clicked'          
            });
            break;
          case 'fill_form':
            console.log('start filling');        
        };
      }
    );
    
    content.js

    {
      "manifest_version": 2,
    
      "name": "Automater",  
      "version": "0.0.1",
    
      "page_action": {
        "default_title": "Click here!",
        "default_icon": "icon.png"
      },
      "content_scripts": [
        {
          "matches": [
            "https://www.website.com/*"
          ],
          "js": ["jquery-3.2.1.min.js", "content.js"],
          "run_at": "document_end"
        }
      ],
      "background": {
        "scripts": ["background.js"],
        "persistent": false
      },
      "permissions": [
        "activeTab",
        "tabs",
        "declarativeContent",
        "storage"
      ]
    }
    
    chrome.pageAction.onClicked.addListener(function(tab) {
      chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
        var activeTab = tabs[0];
        chrome.tabs.sendMessage(
          activeTab.id,
          { 'message': 'click_btn' }
        );
      });
    });
    
    chrome.runtime.onInstalled.addListener(function() {
      chrome.declarativeContent.onPageChanged.removeRules(
          undefined, function() {
        chrome.declarativeContent.onPageChanged.addRules([
          {
            conditions: [
              new chrome.declarativeContent.PageStateMatcher({
                pageUrl: {
                  urlContains: 'www.website.com',
                  schemes: ['https']
                },
              })
            ],
            actions: [ new chrome.declarativeContent.ShowPageAction() ]
          }
        ]);
      });
    });
    
    chrome.windows.onCreated.addListener(function(newWindow) {
      chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
        var activeTab = tabs[0];
        chrome.tabs.sendMessage(
          activeTab.id,
          { 'message': 'fill_form' }
        );
      });
    });
    
    chrome.runtime.onMessage.addListener(
      function(request, sender, sendResponse) {
        if( request.message === 'btn_clicked' ) {
          citationsSize = request.citationsSize;
        }
      }
    );
    
    chrome.runtime.onMessage.addListener(
      function(request, sender, sendResponse) {
        switch(request.message) {
          case 'click_btn':
            $("#btn_id").click();
    
            chrome.runtime.sendMessage({
              "message": 'btn_clicked'          
            });
            break;
          case 'fill_form':
            console.log('start filling');        
        };
      }
    );
    
    我的问题 我在网站上。单击扩展图标后,
    $(“#btn_id”)。单击()起作用,它以弹出窗口的形式打开一个新窗口(这个弹出窗口由我当前所在的网站打开)。我使用
    chrome.windows.onCreated
    捕获新打开的窗口,但是,从这里,我无法向新窗口的内容脚本发送消息
    fill\u form


    如何在新打开的弹出窗口中执行脚本?

    您可以通过多种方式解决此问题,但我认为您并不真正需要消息。如果您希望在单击页面操作时执行内容脚本,则不要将其添加到
    manifest.json
    ,而是将其拆分为两个不同的文件,一个用于单击按钮,另一个用于填充和发送表单,然后在需要时使用
    chrome.tabs.executeScript
    以编程方式注入它们

    工作流程如下所示:

  • 单击页面操作
  • content\u click\u btn.js
    加载到页面中并单击按钮
  • 弹出窗口打开
  • content\u fill\u form.js
    被注入弹出窗口
  • 填写并提交表格
  • 您的代码将如下所示:

    background.js

    chrome.pageAction.onClicked.addListener(function(tab) {
        chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
            chrome.tabs.executeScript(tabs[0].id, {file: 'content_click_btn.js', runAt: 'document_end'});
        });
    });
    
    chrome.runtime.onInstalled.addListener(function() {
        chrome.declarativeContent.onPageChanged.removeRules(undefined, function() {
            chrome.declarativeContent.onPageChanged.addRules([{
                conditions: [
                    new chrome.declarativeContent.PageStateMatcher({
                        pageUrl: {
                            urlContains: 'www.website.com',
                            schemes: ['https']
                        },
                    })
                ],
    
                actions: [ new chrome.declarativeContent.ShowPageAction() ]
            }]);
        });
    });
    
    function listener(newWindow) {
        chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
            if (tabs[0].url.includes('http://www.website.com')
                chrome.tabs.executeScript(tabs[0].id, {file: 'content_fill_form.js', runAt: 'document_end'});
        });
    
        chrome.windows.onCreated.removeListener(listener);
    }
    
    chrome.windows.onCreated.addListener(listener);
    document.getElementById('btn_id').click();
    
    console.log('Filling the form...');
    // Do something to fill and send the form.
    
    内容\u单击\u btn.js

    chrome.pageAction.onClicked.addListener(function(tab) {
        chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
            chrome.tabs.executeScript(tabs[0].id, {file: 'content_click_btn.js', runAt: 'document_end'});
        });
    });
    
    chrome.runtime.onInstalled.addListener(function() {
        chrome.declarativeContent.onPageChanged.removeRules(undefined, function() {
            chrome.declarativeContent.onPageChanged.addRules([{
                conditions: [
                    new chrome.declarativeContent.PageStateMatcher({
                        pageUrl: {
                            urlContains: 'www.website.com',
                            schemes: ['https']
                        },
                    })
                ],
    
                actions: [ new chrome.declarativeContent.ShowPageAction() ]
            }]);
        });
    });
    
    function listener(newWindow) {
        chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
            if (tabs[0].url.includes('http://www.website.com')
                chrome.tabs.executeScript(tabs[0].id, {file: 'content_fill_form.js', runAt: 'document_end'});
        });
    
        chrome.windows.onCreated.removeListener(listener);
    }
    
    chrome.windows.onCreated.addListener(listener);
    document.getElementById('btn_id').click();
    
    console.log('Filling the form...');
    // Do something to fill and send the form.
    
    content\u fill\u form.js

    chrome.pageAction.onClicked.addListener(function(tab) {
        chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
            chrome.tabs.executeScript(tabs[0].id, {file: 'content_click_btn.js', runAt: 'document_end'});
        });
    });
    
    chrome.runtime.onInstalled.addListener(function() {
        chrome.declarativeContent.onPageChanged.removeRules(undefined, function() {
            chrome.declarativeContent.onPageChanged.addRules([{
                conditions: [
                    new chrome.declarativeContent.PageStateMatcher({
                        pageUrl: {
                            urlContains: 'www.website.com',
                            schemes: ['https']
                        },
                    })
                ],
    
                actions: [ new chrome.declarativeContent.ShowPageAction() ]
            }]);
        });
    });
    
    function listener(newWindow) {
        chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
            if (tabs[0].url.includes('http://www.website.com')
                chrome.tabs.executeScript(tabs[0].id, {file: 'content_fill_form.js', runAt: 'document_end'});
        });
    
        chrome.windows.onCreated.removeListener(listener);
    }
    
    chrome.windows.onCreated.addListener(listener);
    document.getElementById('btn_id').click();
    
    console.log('Filling the form...');
    // Do something to fill and send the form.
    

    另外,您实际上并不需要它,但是如果您想使用jQuery,您可以将它保留在清单中的
    “content\u scripts”
    字段中。

    在发送消息后,内容脚本将被注入。通过在新窗口、源面板、内容脚本子面板中打开devtools进行检查。您只需在sendMessage之前添加一个超时,或者在onCreated中使用chrome.tabs.onUpdated。@wOxxOm:多亏了您的评论,我可以确保内容脚本被注入。使用
    chrome.tabs.onUpdated
    完美地解决了我的问题。感谢您的解决方案,我的问题是使用
    windows.onCreated
    创建新的弹出窗口后,
    内容脚本
    不会执行。作为@wOxxOm注释,我需要将其放在
    选项卡中。你的方法符合我在问题中的“简化”流程。但是,在提交之后,我还想听听/检查/捕获上一次提交表单的响应。我将尝试用您的方法重新组织我的代码,它具有更好的代码管理设计。@FiriceNguyen不客气,请记住,您可以使用webRequest API轻松拦截像这样的请求/响应。是的,
    webRequest
    API对我的流程非常有帮助。再次感谢你。