【问题标题】:How to listen for url change with Chrome Extension如何使用 Chrome 扩展程序监听 url 变化
【发布时间】:2016-04-29 16:18:55
【问题描述】:

我正在编写一个 Google Chrome 扩展程序来自动执行一些常见任务。我想要的功能如下:

  1. 创建一个新选项卡并导航到我的网络邮件
  2. 输入用户名和密码
  3. 点击“提交”按钮
  4. 等到 webmail 页面出现,然后选择“roundcube”客户端。

我已经完成了第 1、2 和 3 步,并且它们有效。我在提交凭据后尝试侦听 url 更改时遇到了很多麻烦,以便选择 roundcube 客户端的函数可以运行

我知道当客户端选择页面出现时,我可以通过添加到我的清单来运行脚本,但我想使用“chrome.tabs.executeScript”,这样只有当我从 chrome 扩展运行脚本而不是如果我手动进入客户选择页面。

这是我的 manifest.json:

{
  "manifest_version": 2,

  "name"       : "Chrome Autobot",
  "description": "This extension will run various automation scripts for google chrome",
  "version"    : "1.0",

  "browser_action" : {
    "default_icon" : "icon.png",
    "default_popup": "index.html"
  },
  "permissions": [
    "activeTab",
    "webNavigation",
    "tabs",
    "http://*/*",
    "https://*/*"
  ]
}

这是我的 chrome 脚本:

jQuery(function($) {
    "Use Strict";

    var openWebmail = function() {
        chrome.tabs.create({
            url: 'http://mywebmaillogin.com:2095/'
        }, function() {
            chrome.tabs.executeScript(null, {file: "scripts/openEmail.js"});
        });
        chrome.tabs.onUpdated.addListener(function(){
            chrome.tabs.executeScript(null, {file: "scripts/openEmail.js"});
            alert('i work');
        });
    };

    var init = $('.script-init');
    init.on('click', function() {
        openWebmail();
    });

});

这里是作为选项卡创建回调执行的内容脚本(当获取电子邮件登录页面并且加载了 DOM 时),以及当提交电子邮件凭据并且加载了客户端选择页面的 DOM 时(现在不工作)

var openEmail = function() {
    var loc = window.location.href;
    if(loc === 'http://mywebmaillogin.com:2095/') {
        var submit = document.getElementById('login_submit');
        user.value = 'myusername';
        pass.value = 'mypassword';
        if(user.value === 'myusername' && pass.value === 'mypassword') {
            submit.click();
        }
        else {
            openEmail();
        }
    }
    if(loc.indexOf('http://mywebmaillogin:2095/') > -1 && loc.indexOf('login=1') > -1) {
        alert('I work');
    }
}()

任何帮助将不胜感激...谢谢!

【问题讨论】:

    标签: javascript jquery google-chrome google-chrome-extension


    【解决方案1】:

    基于/感谢@ztrat4dkyle 的回答,什么对我有用:

    manifest.json

    {
      ...
      "background": {
        "scripts":["background.js"]
      },
      "content_scripts": [
        {
          "matches": ["http://*/*", "https://*/*"],
          "js": ["content.js"]
        }
      ],
      "permissions": [
        "tabs"
      ]
    }
    

    background.js

    chrome.runtime.onInstalled.addListener(function() {
      // ...
    
      chrome.tabs.onUpdated.addListener(function (tabId, changeInfo, tab) {
        // changeInfo object: https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/tabs/onUpdated#changeInfo
        // status is more reliable (in my case)
        // use "alert(JSON.stringify(changeInfo))" to check what's available and works in your case
        if (changeInfo.status === 'complete') {
          chrome.tabs.sendMessage(tabId, {
            message: 'TabUpdated'
          });
        }
      })
    });
    

    content.js

    chrome.runtime.onMessage.addListener(function (request, sender, sendResponse) {
      if (request.message === 'TabUpdated') {
        console.log(document.location.href);
      }
    })
    

    【讨论】:

      【解决方案2】:

      使用chrome.tabs.onUpdated

      Maifest.json

      {
        "name": "My test extension",
        "version": "1",
        "manifest_version": 2,
        "background": {
          "scripts":["background.js"]
        },
        "content_scripts": [
          {
            "matches": ["http://*/*", "https://*/*"],
            "js": ["contentscript.js"]
          }
        ],
        "permissions": [
          "tabs"
        ]
      }
      

      contentscript.js

       chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) {
          alert('updated from contentscript');
       });
      

      background.js

      chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) {
          alert('updated from background');
      });
      

      【讨论】:

      • 为什么需要在 contentscript.js 和 background.js 中添加两次 tabs.onUpdated 监听器?
      • 你不必同时使用两者,选择你需要处理的那个。注意:background.js 中的回调函数接收相同的参数。
      • contentscript.js 不起作用,不能从内容脚本调用 chrome api,参考:stackoverflow.com/questions/24024682/…
      【解决方案3】:

      正如 NycCompSci 所述,您不能从内容脚本调用 chrome api。我能够通过消息传递将 api 数据传递给内容脚本,所以我想在这里分享一下。首先在 background.js 中调用onUpdated

      清单

      {
        "name": "My test extension",
        "version": "1",
        "manifest_version": 2,
        "background": {
          "scripts":["background.js"]
        },
        "content_scripts": [
          {
            "matches": ["http://*/*", "https://*/*"],
            "js": ["contentscript.js"]
          }
        ],
        "permissions": [
          "tabs"
        ]
      }
      

      background.js

      chrome.tabs.onUpdated.addListener(function
        (tabId, changeInfo, tab) {
          // read changeInfo data and do something with it (like read the url)
          if (changeInfo.url) {
            // do something here
      
          }
        }
      );
      

      然后您可以扩展该脚本以将数据(包括新的 url and other chrome.tabs.onUpdated info)从 background.js 发送到您的内容脚本,如下所示:

      background.js

      chrome.tabs.onUpdated.addListener(
        function(tabId, changeInfo, tab) {
          // read changeInfo data and do something with it
          // like send the new url to contentscripts.js
          if (changeInfo.url) {
            chrome.tabs.sendMessage( tabId, {
              message: 'hello!',
              url: changeInfo.url
            })
          }
        }
      );
      

      现在您只需要在内容脚本中监听该数据:

      contentscript.js

      chrome.runtime.onMessage.addListener(
        function(request, sender, sendResponse) {
          // listen for messages sent from background.js
          if (request.message === 'hello!') {
            console.log(request.url) // new url is now in content scripts!
          }
      });
      

      希望对某人有所帮助! ʘ‿ʘ

      【讨论】:

      • 你指的是什么“回调”?可能是您的权限不允许数据传输,因此请确保您的清单设置如上。我建议从上面的示例开始并对其进行调整,因为它肯定可以在新的扩展中使用。
      • 我拥有所有权限,包括选项卡,但在此架构中,我没有收到任何函数调用。伤心。
      • 抱歉,Marcelo,你说的不是很具体,所以在这里很难提供帮助。我建议通过在函数的第一行添加console.log(data) 来解决问题,其中data 是您尝试使用的数据,然后查看控制台以查看它是否存在。如果没有,您很可能会发现一个错误,您可以搜索帮助:)
      • @ztrat4dkyle 如何在首页加载时也触发消息?
      • 这是一个好方法,但在我的情况下,changeInfo 对象只有status 属性,所以使用@SynergyChen 答案---您可以在其中测试changeInfo.status 属性,然后在传递消息后从内容脚本中获取 URL。
      猜你喜欢
      • 2013-01-26
      • 1970-01-01
      • 2013-11-30
      • 2014-10-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-05-12
      • 2014-09-26
      相关资源
      最近更新 更多