chrome浏览器插件content.js和background.js还有popup都是什么,怎么通讯

popup

在用户点击扩展程序图标时(下图中的下载图标),都可以设置弹出一个popup页面。而这个页面中自然是可以包含运行的js脚本的(比如就叫popup.js)。它会在每次点击插件图标——popup页面弹出时,重新载入。

content_scripts脚本

content_script 是植入型的,它会被植入到符合匹配的网站页面上。在页面加载完成后执行。content_script 最有用的地方是操作网站页面上的DOM。一切平时做前端的一些操作它都可以做,像什么添加、修改、删除 DOM,获取 DOM 值,监听事件等等,都可以很容易的做到。所以,如果想获取人家的登录帐户和密码,就是件非常容易的事,只需要添加content_script,监听帐户和密码的文本框,获得值后将数据发送到自己的服务器就可以了。因此,特别说明,别乱装扩展,特别是不从官方扩展库里下载的扩展。配置如下:

 "content_scripts": [
        {
            "matches": [ "http://*/*", "https://*/*" ],
            "js": ["content_scripts.js"]
        }
    ],

这样,在页面加载完成后,就会加载 content.js,在 content.js 里,就可以控制页面元素。可在浏览器进行调试,位置如图,调试的方法就是浏览器调试js的方法,加断点,执行: 

background_script脚本

插件存在则存在, 随着浏览器的打开而打开,随着浏览器的关闭而关闭, 通常把需要一直运行的、启动就运行的、全局的代码放在background里面。它没办法控制页面元素,但可以通过 content_script 告诉它。ajax同理,如果要在页面打开时向别的服务器请求数据,这时就可以告诉 background_script,让它去请求,然后把返回的数据发送给 content_script。这样就不会受到浏览器的安全限制影响。

background的权限非常高,几乎可以调用所有的Chrome扩展API(除了devtools),而且它可以无限制跨域,也就是可以跨域访问任何网站而无需要求对方设置CORS。

使用 background_script
要使用 background_script,需要在 manifest.json 中配置,如下:

    "background": {
        "scripts": ["background.js"],
        "persistent": false
    },

如果要调试,可以打开插件一个tab页或者popup页的检查,或者点击背景图:

消息传递

在网页实际运行过程中,原始web+注入的的content_scripts+background.js=新的web页面,当打开多个页面时,就会存在多个新的web页面。因为每个页面都注入content_scripts。那么在通信的时候,后台脚本或则popup页面,怎么确定是与那个页面进行消息交互呢,通过tabID。

tab是什么呢?

上图就有三个tab标签,也就是在浏览器中打开的网页对应着一个tab,图中第二个和第三个虽然url相同,但tabid不一样。三个主要部分消息交互机制如下图:

background 和 content_scripts 的通信

接收消息:chrome.runtime.onMessage.addListener

发送消息:chrome.runtime.sendMessage 

content_scripts发送和接收消息:

let btn = document.querySelector('button');  // 页面DOM
btn.onclick = function () {
  sendMsg()
};
 
// 发送消息
function sendMsg() {
  chrome.runtime.sendMessage({ origin: 'pageJs' }, function (data) {
    // 接受返回信息
    console.log("🔷: content_scripts.js  send");
    console.log("🔷: content_scripts.js  sendBack", data);
    console.log('.....................');
  });
}
 
 
 
// 接受信息
function receiveMsg() {
  chrome.runtime.onMessage.addListener(function (data, sender, sendResponse) {
    console.log("👀: content_scripts.js  receive", data);
    console.log("👀: content_scripts.js  receiveFn");
    sendResponse(data);
    console.log('.....................');
  });
};
receiveMsg();

background发送和接收消息:

// 接收到信息
function receiveMsg() {
  // data数据  sender发送方  sendResponse回调
  chrome.runtime.onMessage.addListener(function (data, sender, sendResponse) {
    console.log("😝: background.js  receive", data);
    console.log("😝: background.js  receiveFn");
    sendResponse(data)
    console.log('.....................');
    tabs();
  });
};
receiveMsg();
 
 
// 监测到新的tab
async function tabs() {
  const tabId = await getCurrentTabId();
  // 在背景页面发送消息,需要当前 tabID
  chrome.tabs.sendMessage(tabId, { name: 'bJs' }, function (data) {
    console.log("📌: background.js  send");
    console.log("📌: background.js  sendBack", data);
    console.log('.....................');
  });
};
 
 
// 获取当前 tab ID
function getCurrentTabId() {
  return new Promise((resolve, reject) => {
    chrome.tabs.query({ active: true, currentWindow: true }, function (tabs) {
      resolve(tabs.length ? tabs[0].id : null)
    });
  })
};

所有通信之前,发送方和接收方必须都存在,否则报错。

background 和 popup的通信

收消息:在background中: chrome.extension.getViews() 获取当前插件内每个运行页面的窗口数组([window, window])

发送消息:在右上角弹出框中:chrome.extension.getBackgroundPage() 获取背景页面的窗口对象(window)

background.js在原来基础上增加一个通信函数:

/**
 * 通信函数
 */
function backFun(...arg) {
  const allViews = chrome.extension.getViews()
  console.log(arg);
  console.log('chrome.extension.getViews():', allViews)
}

popup.js页面增加: 

let btn = document.getElementById('submit');
 
// 可以获取到background.js中设置的函数,
const background = chrome.extension.getBackgroundPage();
 
// 点击按钮
btn.onclick = function (e) {
  var name = document.getElementById('name').value;
  var password = document.getElementById('password').value;
  // sendMsg(name, password);
  background.backFun(name, password)
}

content_scripts 和 popup的通信

content_scripts.js里面:

let btn = document.getElementById('submit');
 
// 点击按钮
btn.onclick = function (e) {
  var name = document.getElementById('name').value;
  var password = document.getElementById('password').value;
  tabs(name, password);
}
 
// 去链接,对应的tab标签页面
async function tabs(...arg) {
  const tabId = await getCurrentTabId();
  const connect = chrome.tabs.connect(tabId, { name: 'popup' }); 
  // 和指定tabID建立链接,并设置信号名字
  // 发送信息
  connect.postMessage(arg);
 
  // 接受返回信息
  connect.onMessage.addListener(mess => {
    console.log(mess)
  })
};
 
 
// 获取当前 tab ID
function getCurrentTabId() {
  return new Promise((resolve, reject) => {
    chrome.tabs.query({ active: true, currentWindow: true }, function (tabs) {
      resolve(tabs.length ? tabs[0].id : null)
    });
  })
};
 
 

popup.js:

// 监听链接
chrome.runtime.onConnect.addListener(res => {
  if (res.name == "popup") {
    res.onMessage.addListener(mes => {
      console.log('🥓: popup.js receive', mes);
      res.postMessage('📣: popup.js receiveBack')
    });
  }
});

弹出框只要点击插件才能弹出,而当你操作页面的时候,插件弹框又会消失…消失之后,弹框的.js等都会销毁…所以,可以向background通信,然后点击弹出之后,弹出框和background通信,或者弹出之后直接向content_scripts通信。

content_scripts 和 popup的通信也可以通过另外方式传递

content_scripts.js:

// 点击按钮
btn.onclick = function (e) {
  var name = document.getElementById('name').value;
  var password = document.getElementById('password').value;
  tabs(name, password);
}
 
// 去链接,对应的tab标签页面
async function tabs(...arg) {
  const tabId = await getCurrentTabId();
  // 页面发送消息,需要当前 tabID
  chrome.tabs.sendMessage(tabId, { name: 'bJs' }, function (data) {
    console.log("📌: background.js  send");
    console.log("📌: background.js  sendBack", data);
    console.log('.....................');
  });
  
};
 
// 获取当前 tab ID
function getCurrentTabId() {
  return new Promise((resolve, reject) => {
    chrome.tabs.query({ active: true, currentWindow: true }, function (tabs) {
      resolve(tabs.length ? tabs[0].id : null)
    });
  })
};

popup.js:

 chrome.runtime.onMessage.addListener(function (data, sender, sendResponse) {
    console.log("👀: popup.js  receive", data);
    console.log("👀: popup.js  receiveFn");
    sendResponse(data);
    console.log('.....................');
  });

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/436576.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

高并发服务器模型

高并发服务器模型 1.高并发服务器模型--select2.高并发服务器模型--poll3.epoll模型3.1 epoll原理3.2epoll反应堆 1.高并发服务器模型–select 我们知道实现服务器的高并发,可以用多线程或多进程去实现。但还可以利用多路IO技术:select来实现,它可以同时…

html唐诗鉴赏

<!DOCTYPE html> <html> <head><title>文字网页</title> </head> <body><h2 align"center">唐诗鉴赏</h2><hr width"100%" size"1" color"#00ffee"><p align"…

“2024第九届国际发酵培养基应用与发展技术论坛”圆满落幕

3月5日&#xff0c;“2024第九届国际发酵培养基应用与发展技术论坛”在济南圆满落幕。论坛吸引了来自发酵行业400多名代表现场参会&#xff0c;1600多名代表线上参会。本次论坛由中国生物发酵产业协会主办&#xff0c;安琪酵母股份有限公司承办。中国生物发酵产业协会理事长于学…

抽奖小程序怎么一键生成_揭秘这款火爆的抽奖小程序

一键生成&#xff0c;梦想触手可及&#xff01;揭秘这款火爆的抽奖小程序 在快节奏的现代生活中&#xff0c;每个人都渴望找到一份属于自己的幸运与惊喜。而今天&#xff0c;我要为大家介绍的这款抽奖小程序&#xff0c;正是实现这一愿望的神器&#xff01;它不仅操作简单&…

Linux服务器安装nvm

1、 首先查看服务器有没有安装git git --version 2、如果没有安装&#xff1a;在Linux上是有yum安装Git&#xff0c;非常简单&#xff0c;只需要一行命令 yum -y install git 3、git安装完成后&#xff0c;使用以下其中一个命安装NVM # 能访问github的话&#xff0c;使用这…

逆变器专题(17)-下垂控制(1)

相应仿真原件请移步资源下载 通常情况下&#xff0c;离网型逆变器采用的控制方法为电压电流双闭环控制&#xff0c;而常规的电压电流双闭环控制会存在电压跌落&#xff0c;频率失稳等情况&#xff0c;通俗的将就是没有电压和频率的支撑 。 下垂控制是现如今较为常用的李网逆变…

Python接口自动化之cookie、session应用!

以下介绍cookie、session原理及在接口自动化中的应用。 HTTP 协议是一种无状态协议&#xff0c;即每次服务端接收到客户端的请求时&#xff0c;都是一个全新的请求&#xff0c;服务器并不知道客户端的历史请求记录&#xff1b;Session 和 Cookie 的主要目的就是为了弥补 HTTP 的…

运维工单系统哪家好?

数字化转型数字化时代已然到来&#xff0c;企业运维工作的重要性日益突出。为了满足各类企业的运维需求&#xff0c;市场上涌现了诸多运维工单系统厂家&#xff0c;包括卓豪ServiceDesk Plus、Zendesk、Zenduty、Jira Service Desk等。 而选择合适的运维工单系统&#xff0c;对…

《剑指 Offer》专项突破版 - 面试题 74 : 合并区间(C++ 实现)

题目链接&#xff1a;LCR 074. 合并区间 - 力扣&#xff08;LeetCode&#xff09; 题目&#xff1a; 输入一个区间的集合&#xff0c;请将重叠的区间合并。每个区间用两个数字表示&#xff0c;它们分别表示区间的起始位置和结束位置。例如&#xff0c;输入区间集合 [[1, 3], …

【异常处理】BadSqlGrammarException低级SQL语法异常

报错 org.springframework.jdbc.BadSqlGrammarException: ### Error querying database. Cause: java.sql.SQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use …

每日一练 | 华为认证真题练习Day194

1、下面是路由器Huawei的部分输出配置&#xff0c;关于该部分配置描迷正确的是: [huawei] bgp 100 [huawei-bgp]peer 12.12.12.2 ip-prefix P1 export [huawei]ip-prefix P1 index 5 deny 10.0.0.0 0 greater-equal 8 less-equal 32 [huawei]ip-prefix P1 index 5 deny 172…

做副业千万不要在抖音开个人店,个人店血泪史,千万别碰!

大家好&#xff0c;我是电商花花。 抖音小店个人店已经开放了很长时间了&#xff0c;个人店以不用营业执照&#xff0c;不用保证金&#xff0c;凭借身份证就可以在抖音上开抖音小店&#xff0c;就可以做电商&#xff0c;做老板。 目前抖音小店的流量可以说是非常大&#xff0…

【MetaGPT】多智能体协作——你画我猜(文字版)

多智能体协作 本篇将学习 MetaGPT中的 Environment 、 Team 组件。 1. Muti Agent 概念概述 多智能体系统 (Multi-Agent System, MAS) 是由一群具有一定自主性、协同性和学习能力的智能体组成的系统。智能体在环境中相互协作&#xff0c;以达到某种目标或完成特定任务。 2. 多…

哪里下载Mac上最全面的系统清理工具,CleanMyMac X4.15中文版永久版资源啊

哪里下载Mac上最全面的系统清理工具&#xff0c;CleanMyMac X4.15中文版永久版资源啊&#xff0c;CleanMyMac X4.15中文版是一款全面的Mac系统优化工具。它能够扫描、检测并清理不需要的文件和应用程序&#xff0c;优化内存使用和磁盘空间&#xff0c;提高Mac的性能表现。此外&…

运行json文件变成api服务器模拟,json-server

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 json-server数据运行 json-server数据运行 安装json-server // 命令 路径 端口 "server": "json-server ./server/data.json --port 8080",

LeetCode 2673. 使二叉树所有路径值相等的最小代价【贪心】1917

本文属于「征服LeetCode」系列文章之一&#xff0c;这一系列正式开始于2021/08/12。由于LeetCode上部分题目有锁&#xff0c;本系列将至少持续到刷完所有无锁题之日为止&#xff1b;由于LeetCode还在不断地创建新题&#xff0c;本系列的终止日期可能是永远。在这一系列刷题文章…

C语言指针总结(完结篇)

前言 这篇博客终于迎来了指针博客的大结局&#xff0c;本篇主要分析习题来回顾之前的指针总结的知识点&#xff0c;这篇博客的题有点绕&#xff0c;哈哈算是经典了 个人主页&#xff1a;小张同学zkf 若有问题 评论区见 感兴趣就关注一下吧 目录 1. sizeof和strlen的对比 1.1 …

Python算法100例-3.6 自守数

1.问题描述2.问题分析3.算法设计4.求给定数的位数5.分离给定数中的最后几位6.确定程序框架7.完整的程序 1&#xff0e;问题描述 自守数是指一个数的平方的尾数等于该数自身的自然数。例如&#xff0c; 5 2 25 &#xff0c; 2 5 2 625 &#xff0c; 7 6 2 5776 &#xff0c…

oss-fuzz-gen:一款基于LLM的模糊测试对象生成与评估框架

关于oss-fuzz-gen oss-fuzz-gen是一款基于LLM的模糊测试对象生成与评估框架&#xff0c;该工具可以帮助广大研究人员使用多种大语言模型&#xff08;LLM&#xff09;生成真实场景中的C/C项目以执行模糊测试。 该工具基于Google的OSS-Fuzz平台实现其功能&#xff0c;并对生成的…

参加美国大学生数学建模大赛,Matlab和Python该怎么选?

经常有小伙伴在数学建模竞赛会问到&#xff0c;MATLAB和Python到底哪个更好&#xff1f;这个问题一直困惑很多同学&#xff0c;今天数乐君来给大家从实用型来综合分析一下&#xff1a; 首先从两者各自的应用做个对比。 一、python的优势 Python相对于Matlab最大的优势&#…