当前位置: 首页 > 面试题库 >

从Background.js在页面级执行代码并返回值

狄飞鹏
2023-03-14
问题内容

我有一个网页,其中包含自己的脚本和变量,我需要执行这些脚本和变量并从扩展程序的Background.js中检索返回值。

我了解(我认为!),为了与网页进行交互,必须通过chrome.tabs.executeScript或ContentScript完成此操作,但是因为代码必须在原始页面的上下文中执行(为了具有作用域)
(脚本和变量),则需要先将其注入页面。

到目前为止,这就是我所得到的…

网页代码 (我想与之交互):

<html>
<head>
<script>
    var favColor = "Blue";

    function getURL() {
      return window.location.href;
    }
</script>
</head>

<body>
    <p>Example web page with script content I want interact with...</p>
</body>
</html>

manifest.json

{
  // Extension ID: behakphdmjpjhhbilolgcfgpnpcoamaa
  "name": "MyExtension",
  "version": "1.0",
  "manifest_version": 2,
  "description": "My Desc Here",
  "background": {
    "scripts": ["background.js"]
  },  
  "icons": {
    "128": "icon-128px.png"
  },
  "permissions": [
    "background",
    "tabs",
    "http://*/",
    "https://*/",
    "file://*/",           //### (DEBUG ONLY)
    "nativeMessaging"
  ]
}

background.js

codeToExec = ['var actualCode = "alert(favColor)";',
                  'var script = document.createElement("script");',
                  ' script.textContent = actualCode;',
                  '(document.head||document.documentElement).appendChild(script);',
                  'script.parentNode.removeChild(script);'].join('\n');
chrome.tabs.executeScript( tab.id, {code:codeToExec}, function(result) {
   console.log('Result = ' + result);
} );

我意识到代码当前只是在“更改”
favColor变量(这只是一项测试,以确保我可以看到它正常工作)。但是,如果我尝试返回该变量(通过将其保留为最后一条语句或说“ returnfavColor”),则executeScript回调将永远没有该值。

因此,这里似乎有(至少)三个级别:

  1. background.js
  2. 内容脚本
  3. 实际网页 (包含脚本/变量)

…我想知道从1级到3级(以上)并返回值的推荐方法是什么?

在此先感谢:o)


问题答案:

您完全理解3层上下文分离。

  • 背景页面是一个单独的页面,因此不会与可见页面共享JS或DOM。
  • 内容脚本与网页的JS上下文隔离,但共享DOM。
  • 您可以使用共享DOM将代码注入页面的上下文中。它可以访问JS上下文,但不能访问Chrome API。

为了进行通信,这些层使用不同的方法:

*通过Chrome API进行 *背景 <->内容交流。
最原始的是的回调executeScript,但除了单行代码外,这对于任何其他情况都是不切实际的。
常用的方法是使用Messaging。
不常见,但可以使用chrome.storage及其onChanged事件进行通信。

页面 <->扩展名不能使用相同的技术。
由于注入的页面上下文脚本在技术上与页面本身的脚本没有什么区别,因此您正在寻找一种与扩展程序对话的网页方法。有两种可用的方法:

  1. 尽管页面对chrome.*API的访问非常非常有限,但它们仍可以使用消息传递来联系扩展。这是通过"externally_connectable"方法实现的。

好处是直接与扩展程序对话,但缺点是 需要从中专门将您正在使用的域白名单加入白名单
,并且您需要跟踪扩展名ID(但是由于要注入代码,因此您可以提供带有ID的代码)。如果需要在任何域上使用它,则不合适。

  1. 另一个解决方案是使用DOM事件。由于DOM在内容脚本和页面脚本之间共享,因此由一个人生成的事件将对另一个人可见。

该文档演示了如何使用window.postMessage此效果。从概念上讲,使用自定义事件更为清晰。

这种方法的缺点是 要求内容脚本充当代理 。这些脚本中必须包含以下内容:

    window.addEventListener("PassToBackground", function(evt) {
  chrome.runtime.sendMessage(evt.detail);
}, false);

而后台脚本使用chrome.runtime.onMessage侦听器对此进行处理。

我建议您编写一个单独的内容脚本,并executeScript使用file属性而不是进行调用code,而不要依赖其回调。消息传递更加简洁,可以多次将数据返回到后台脚本。



 类似资料:
  • 问题内容: 我正在从PHP调用python脚本。 python程序必须根据传递给它的参数返回一些值。 这是一个示例python程序,它将为您提供我目前正在做什么的基本概念: 从上面的代码中可以看到,我的基本目标是 以便python程序根据参数返回一些值(0、1、4、8等)。 然后,调用PHP的程序访问这些返回的值并执行适当的操作。 目前,我已经为此目的使用了“ sys.exit(n)”。 我使用s

  • 问题内容: 我有一个Android应用程序项目,突然停止工作。显然没有错误,但是当我尝试启动时,我得到了: 执行Aapt时出错:返回码139 我试图清理该项目及其相关的库项目,重新启动Eclipse,更新为最新的ADT和SDK版本,等等,但是都失败了。有时我还会遇到其他错误(不进行任何更改): 生成最终归档文件时出错:java.io.FileNotFoundException:… / bin /

  • 我正在尝试使用pcregrep命令解析一组正则表达式。该命令将从python执行,输出被格式化并存储在python数据结构中。我能执行所有的正则表达式,除了下面这个 我正在打印错误代码以及通过从python执行pcgreep命令获得的消息。 我得到的错误代码是256,并且是空消息,我使用的是python的命令实用程序。我正在打印cmd_output[0](用于返回代码)和command_outpu

  • 本文向大家介绍微信小程序判断页面是否从其他页面返回的实例代码,包括了微信小程序判断页面是否从其他页面返回的实例代码的使用技巧和注意事项,需要的朋友参考一下 微信小程序判断页面是否从其他页面返回,具体内容如下所示: 在 data 中自定义一个标记变量,在onLoad里 ps:下面看下微信小程序 判断当前页面是重新打开,还是从其他页面返回 在小程序中设置变量用来判断是否是从其他页面返回 在 data

  • 问题内容: 在我的特定情况下,我有两种解决方案。我想找出哪一种更可行。在这种情况下,我还可以通过从服务器端代码返回JSON对象来实现自己的目标。但是,我不知道它是如何完成的,最好的方法是什么。 首先,我不需要完整的aspx页面,因为我只需要从代码返回的响应即可。那么,我是否使用Web服务,处理程序,或者是否有其他特定方法来执行此操作? 这个解决方案可行吗?我是否使用该类构建JSON字符串并将该字符

  • 本文向大家介绍6行代码实现微信小程序页面返回顶部效果,包括了6行代码实现微信小程序页面返回顶部效果的使用技巧和注意事项,需要的朋友参考一下 本文实例为大家分享了微信小程序页面返回顶部的具体代码,供大家参考,具体内容如下 效果预览: js部分: wxml部分: wxss部分: 以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持呐喊教程。