如何使用Chrome扩展程序监听网址更改

Hel*_*rld 20 javascript jquery google-chrome google-chrome-extension

我正在撰写Google Chrome扩展程序,以自动完成一些常见任务.我想要的功能如下:

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

我已完成步骤1,2和3,他们工作.我提交凭据后尝试侦听网址更改时遇到很多麻烦,以便选择圆形客户端的功能可以运行

我知道我可以通过添加到我的清单来显示客户端选择页面时运行脚本但是我想使用"chrome.tabs.executeScript",这样只有当我从chrome扩展程序运行脚本时才选择roundcube而不是我去手动选择客户端页面.

这是我的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://*/*"
  ]
}
Run Code Online (Sandbox Code Playgroud)

这是我的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();
    });

});
Run Code Online (Sandbox Code Playgroud)

这里是作为标签创建回调执行的内容脚本(当提取电子邮件登录页面并加载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');
    }
}()
Run Code Online (Sandbox Code Playgroud)

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

ztr*_*yle 29

正如NycCompSci所提到的,你不能从内容脚本中调用chrome api.我能够通过消息传递将api数据传递给内容脚本,所以我想在这里分享一下.第一次调用onUpdatedbackground.js:

表现

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

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

    }
  }
);
Run Code Online (Sandbox Code Playgroud)

然后,您可以展开该脚本,将background.js中的数据(包括新的url 和其他chrome.tabs.onUpdated信息)发送到您的内容脚本,如下所示:

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
      })
    }
  }
);
Run Code Online (Sandbox Code Playgroud)

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

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!
    }
});
Run Code Online (Sandbox Code Playgroud)

希望有人帮助!ʘ‿ʘ

  • 我具有所有权限,包括选项卡,但是在此架构中,我没有收到任何函数调用。伤心。 (2认同)
  • 这是一个很好的方法,但是在我的例子中,`changeInfo`对象只有`status`属性,所以使用@SynergyChen答案——在其中测试`changeInfo.status`属性,然后从在消息传达后的内容脚本中。 (2认同)
  • 迟到了,但是@KeithDC 或任何有同样问题的人。您需要在manifest.json 中添加“tabs”作为权限,以启用changeInfo 对象中的“url”属性。 (2认同)

小智 17

使用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"
  ]
}
Run Code Online (Sandbox Code Playgroud)

contentscript.js

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

background.js

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

  • contentscript.js不起作用,您不能从内容脚本调用chrome api,请参阅此参考:/sf/ask/1681727771/ (32认同)
  • 为什么你需要在 contentscript.js 和 background.js 上两次添加这个 tabs.onUpdated 监听器? (4认同)

Syn*_*hen 7

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

清单.json

{
  ...
  "background": {
    "scripts":["background.js"]
  },
  "content_scripts": [
    {
      "matches": ["http://*/*", "https://*/*"],
      "js": ["content.js"]
    }
  ],
  "permissions": [
    "tabs"
  ]
}
Run Code Online (Sandbox Code Playgroud)

背景.js

{
  ...
  "background": {
    "scripts":["background.js"]
  },
  "content_scripts": [
    {
      "matches": ["http://*/*", "https://*/*"],
      "js": ["content.js"]
    }
  ],
  "permissions": [
    "tabs"
  ]
}
Run Code Online (Sandbox Code Playgroud)

内容.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'
      });
    }
  })
});
Run Code Online (Sandbox Code Playgroud)