popup组件在退出时脚本停止运行

只有background组件可以持续运行,需要调用background脚本来运行你的后台任务,参考
image.png
popup脚本发送请求给background脚本可以参考如下

  1. bg = chrome.extension.getBackgroundPage(); // get background scripts
  2. bg.add_1(params); // call background func

当然也可以把background func绑定到popup的一些组件上

  1. buttonOne = document.getElementById('btn_add_one');
  2. buttonOne.onclick = bg.add_1;

那如何反向传递呢?没找到好的方法,可以参考
https://stackoverflow.com/questions/15948283/can-i-call-the-function-inside-popup-js-from-background-js
的回答,使用event来做,但是感觉不太对
background.js:
chrome.runtime.sendMessage({yourMsg: 'Your Msg'});

popup.js:

  1. chrome.runtime.onMessage.addListener(function(message) {
  2. //here you can call your popup.js function
  3. xyz()
  4. });

background组件爬取页面时出现跨域问题

使用大致如下列代码时

  1. req = new XMLHttpRequest();
  2. req.open('GET', url, true);
  3. req.send(null);

其使用的域貌似为你当前浏览器打开的域,执行后台爬虫任务时会失效
image.png
以此增加跨域权限

无法获取已打开html的源代码

一个土办法是后台使用前述代码指行一次html请求,显然不优雅,参考文章
https://stackoverflow.com/questions/11684454/getting-the-source-html-of-the-current-page-from-chrome-extension
简单复制其提供的inject代码加入到项目

  1. // @author Rob W <http://stackoverflow.com/users/938089/rob-w>
  2. // Demo: var serialized_html = DOMtoString(document);
  3. function DOMtoString(document_root) {
  4. var html = '',
  5. node = document_root.firstChild;
  6. while (node) {
  7. switch (node.nodeType) {
  8. case Node.ELEMENT_NODE:
  9. html += node.outerHTML;
  10. break;
  11. case Node.TEXT_NODE:
  12. html += node.nodeValue;
  13. break;
  14. case Node.CDATA_SECTION_NODE:
  15. html += '<![CDATA[' + node.nodeValue + ']]>';
  16. break;
  17. case Node.COMMENT_NODE:
  18. html += '<!--' + node.nodeValue + '-->';
  19. break;
  20. case Node.DOCUMENT_TYPE_NODE:
  21. // (X)HTML documents are identified by public identifiers
  22. html += "<!DOCTYPE " + node.name + (node.publicId ? ' PUBLIC "' + node.publicId + '"' : '') + (!node.publicId && node.systemId ? ' SYSTEM' : '') + (node.systemId ? ' "' + node.systemId + '"' : '') + '>\n';
  23. break;
  24. }
  25. node = node.nextSibling;
  26. }
  27. return html;
  28. }
  29. chrome.runtime.sendMessage({
  30. action: "getSource",
  31. source: DOMtoString(document)
  32. });

在你认为可以的地方执行一次下述函数注入你的js

  1. chrome.tabs.executeScript(null, {
  2. file: "getPagesSource.js"
  3. }, function() {
  4. // If you try and inject into an extensions page or the webstore/NTP you'll get an error
  5. if (chrome.runtime.lastError) {
  6. message.innerText = 'There was an error injecting script : \n' + chrome.runtime.lastError.message;
  7. }
  8. });

注意,getPagesSource.js为前述inject代码
并且在你认为合适的地方(猜测background脚本及popup脚本都可以,我写在popup)加入下述代码以处理由注入脚本发回来的请求

  1. chrome.runtime.onMessage.addListener(function(request, sender) {
  2. if (request.action == "getSource") {
  3. message.innerText = request.source;
  4. // do something with source code
  5. }
  6. });