首页 > 解决方案 > Chrome 扩展程序未检测到脚本 ID

问题描述

我正在创建一个简单的 chrome 扩展,它基本上检测是否存在一个 id 为“x”的脚本加载到用户登陆的页面中,如果我通过 jQuery 调用 id 工作正常,但是当我加载 chrome 扩展时popup.js 它不起作用,我的代码有问题吗?

一些登陆页面html:

 <script data-cfasync="false"  id="somename" type="text/javascript">...

Popup.js

document.addEventListener('DOMContentLoaded', function() {

  console.log($('#clevernt').length);

    if ($('#somename').length == 0) {
    $('#title').html('Script does not exists.<br> <span class="dot-red"></span>');
}else{
$('#title').html('Script exists.<br> <span class="dot-green"></span>');
}

}, false);

清单.json:

{
  "manifest_version": 2,

  "name": "name",
  "description": "This extension will check if clever script is loaded",
  "version": "1.0",

  "browser_action": {
   "default_icon": "icon.png",
   "default_popup": "popup.html"
  },
  "content_scripts":[
   {
     "matches":["<all_urls>"],
     "js":["jquery.js"]
   }  
  ],
  "permissions": [
   "activeTab"
   ]
}

标签: javascriptjquerygoogle-chrome-extension

解决方案


弹出窗口是一个完全独立的扩展页面,其 URL 类似于 chrome-extension://id/popup.html。它与网页无关。

content_scripts部分会自动在网页中运行列出的脚本,而不是在扩展页面中,因此在 manifest.json 中声明的 jquery.js 会加载到网页中,但不会加载到弹出窗口中,因为弹出窗口不是网页。

因此,您的弹出脚本当前没有 jquery.js。如果您打开正确的开发工具,您应该会看到一个错误:因为弹出窗口是单独窗口中的单独页面,它有自己单独的开发工具。在弹出窗口中右键单击,然后单击“检查”以打开正确的开发工具,您将在其中看到错误消息。

目前你的 popup.js 在它自己的弹出页面中寻找一个元素,而不是在网页中。
要访问网页的 DOM,您需要一个内容脚本

  1. 在 popup.html 中加载 jquery.js:<script src=jquery.js></script>
  2. 在结束</body>标记之前在 popup.html 中加载 popup.js,这样您就不需要 DOMcontentLoaded 或 jQuery.ready() 或 $() 包装器:<script src=popup.js></script></body>
  3. content_scripts从 manifest.json中删除部分
  4. 使用程序注入

popup.js:

chrome.tabs.executeScript({code: `(${inContent})()`}, ([result] = []) => {
  $('#title').html(
    chrome.runtime.lastError ? 'Error: ' + chrome.runtime.lastError.message :
      result ? 'Script exists.<br> <span class="dot-green"></span>' :
        'Script does not exist.<br> <span class="dot-red"></span>');
});

// this function will run as a content script code
// so it can't use jQuery because we don't inject it anymore for simplicity
function inContent() {
  // the returned value must be JSON-compatible
  // so we can't return a DOM element
  return !!document.getElementById('somename');
}

推荐阅读