【问题标题】:Chrome Extension Saving Values from Background.js into Storage and displaying on popup.htmlChrome 扩展将值从 Background.js 保存到存储中并在 popup.html 上显示
【发布时间】:2019-04-21 10:57:02
【问题描述】:

我目前正在编写一个简单的 chrome 扩展程序,当您单击标题中的扩展程序图标时,它将当前网页保存到本地存储。

我已按照此处的 Chrome 文档,使用 background.js 成功地将 url 保存到本地存储中:https://developer.chrome.com/extensions/activeTab

我的问题是,当我第一次点击 chrome 扩展程序图标时,我的事件触发但我的 popup.js 出现错误

Uncaught TypeError: Cannot read property 'getSelected' of undefined

background.js

chrome.browserAction.onClicked.addListener(function(tab) {

  console.log('Turning ' + tab.url + ' red!');
  var tabNew = tab.url
  chrome.storage.sync.set({ ["key" + 1]:  tabNew}, function(){
      //  A data saved callback omg so fancy
  });

  chrome.storage.sync.get(/* String or Array */["key" + 1], function(items){
      //  items = [ { "yourBody": "myBody" } ]
      console.log(items)
  });


  chrome.tabs.executeScript({
    code: 'document.body.style.backgroundColor="red"'
  });

  chrome.browserAction.setPopup({popup: 'popup.html'});


});

popup.js

chrome.tabs.getSelected(null, function(tab) {
    document.getElementById('currentLink').innerHTML = tab.url;
});



document.addEventListener('DOMContentLoaded', function() {
    var link = document.getElementById('download');
    // onClick's logic below:
    link.addEventListener('click', function() {
        chrome.storage.sync.get(null, function(items) { // null implies all items
            // Convert object to a string.
            var result = JSON.stringify(items);

            // Save as file
            chrome.downloads.download({
                url: 'data:application/json;base64,' + btoa(result),
                filename: 'filename_of_exported_file.json'
            });
        });        
    });
});

popup.html

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head> 

    <link href='http://fonts.googleapis.com/css?family=Open+Sans' rel='stylesheet' type='text/css'> 
    <link href='style.css' rel='stylesheet' type='text/css'> 

    <title>Discoveroo</title> 

    <!-- <script type="text/javascript" src="https://www.google.com/jsapi"></script>  -->
    <base target="_blank">

</head>

<body>
<p id="currentLink">Loading ...</p>
<hr />
<ul id="savedLinks"></ul>
<script type="text/javascript" src="popup.js"></script>

<button id="download">Download All</button>
</body>
</html>

ma​​nifest.json

{
  "name": "APPNAME",
  "version": "0.1",
  "manifest_version": 2,
  "description": "APP DESC",
  "permissions": ["activeTab", "storage", "downloads", "<all_urls>"], 
  "background": {
    "scripts": ["background.js"],
    "persistent": true
  },
  "content_scripts": [{
    "matches": ["http://*/*", "https://*/*"],
    "js": ["popup.js"]
  }],
  "browser_action": {
    "default_title": "Add this page to my list"
  },
  "icons": {
    "128": "icon.png"
  }
}

【问题讨论】:

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


    【解决方案1】:
    1. 不要将 popup.js 用作内容脚本。您不需要内容脚本。请参阅architecture overview。内容脚本对 chrome API 的访问受限,并在 网页 中运行,而不是在 browserAction 弹出窗口中运行,后者是一个完全独立的完整扩展页面,具有自己的 chrome-extension:// URL 和 own devtools console等,与网页无关。
    2. browserAction.onClicked 不能与弹出 html 同时工作,因此您应该选择一个。在这种情况下,由于您需要显示弹出页面,因此在 manifest.json 中声明它,删除 browserAction.onClicked,将其内部代码放入您的 popup.js
    3. 因此,不需要后台脚本
    4. 可能不需要&lt;all_urls&gt; 权限,因为您已经拥有activeTab,它可以让您在点击扩展图标后完全访问活动标签。
    5. chrome.tabs.getSelected 已弃用,最终将被删除,因此请使用 chrome.tabs.query({active: true, currentWindow: true}, tabs =&gt; { ... })
    6. 无需读取 chrome.storage,因为您已经在 popup.js 中获得了活动 URL。
    7. 关于“omg so fancy”,回调不是任意的怪异,而是一个基本事实的结果:API 是异步的,所以回调在稍后的时间点被调用,就像一次性的“onload”事件监听器。有很多关于异步 JavaScript 的教程。
    8. 使用安全的textContent 属性而不是可能不安全的innerHTML 来显示纯文本字符串,例如URL。

    ma​​nifest.json

    • 删除"background"
    • 删除"content_scripts"
    • 添加"default_popup"

      "browser_action": {
        "default_title": "Add this page to my list",
        "default_popup": "popup.html"
      },
      

    background.js

    删除它。

    popup.js

    您可能需要的旧后台脚本中唯一的东西是 executeScript 和 sync.set 调用。

    chrome.tabs.executeScript({
      code: 'document.body.style.backgroundColor="red"'
    });
    
    chrome.tabs.query({active: true, currentWindow: true}, ([tab]) => {
      document.getElementById('currentLink').textContent = tab.url;
      chrome.storage.sync.set({key1: tab.url});
    });
    

    您还可以加载Mozilla WebExtension polyfill(在 popup.js 之前的 popup.html 中使用 &lt;script&gt; 标签)并切换到 async/await 语法而不是回调:

    (async () => {
      const [tab] = await browser.tabs.query({active: true, currentWindow: true});
      document.getElementById('currentLink').textContent = tab.url;
      await chrome.storage.sync.set({key1: tab.url});
    })();
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-09-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多