chrome扩展程序开发入门 V3

222 阅读3分钟

Extensions are software programs, built on web technologies (such as HTML, CSS, and JavaScript) that enable users to customize the Chrome browsing experience.

6357776a8d6f4c0ab5e15514f77fc2a9~tplv-k3u1fbpfcp-zoom-in-crop-mark:3024:0:0:0.awebp?.png

一、插件基本组成结构与介绍

pp.jpg

1、manifest.json

官网中所有配置项 ;以下将对常见的部分配置项进行讲解。

  {
  "manifest_version": 3,
  "name": "My Extension",
  "version": "versionString",

   // 『重点』action配置项主要用于点击图标弹出框,对于弹出框接受的是html文件
  "action": {
     "default_title": "Click to view a popup",
   	 "default_popup": "popup.html"
   }
    
  // 通俗易懂
  "default_locale": "en",
  "description": "A plain text description",
  "icons": {...},
  "author": ...,

  // 『重点』下面将出现的background.js 配置service work
  "background": {
    // Required
    "service_worker": "service-worker.js",
  },

    // 『重点』下面将出现content_script.js 应用于所有页面上下文的js
  "content_scripts": [
     {
       "matches": ["https://*.nytimes.com/*"],
       "css": ["my-styles.css"],
       "js": ["content-script.js"]
     }
   ],

    // 使用/添加devtools中的功能
  "devtools_page": "devtools.html",
}

2、background.js

background script是扩展的事件处理程序; 它包含对扩展很重要的浏览器事件的侦听器。它处于休眠状态,直到触发事件,然后执行指示的逻辑。有效的后台脚本仅在需要时加载,并在空闲时卸载。

要关注两点:

  • 不使用时终止,需要时重新启动(类似于事件页面)。
  • 无权访问 DOM。(service worker独立于页面)
chrome.runtime.onMessage.addListener((message, callback) => {
  const tabId = getForegroundTabId();
  if (message.data === "setAlarm") {
    chrome.alarms.create({delayInMinutes: 5})
  } else if (message.data === "runLogic") {
    chrome.scripting.executeScript({file: 'logic.js', tabId});
  } else if (message.data === "changeColor") {
    chrome.scripting.executeScript(
        {func: () => document.body.style.backgroundColor="orange", tabId});
  };
});

3、content_script

读取或写入网页的扩展程序使用 content_script。内容脚本包含在已加载到浏览器的页面上下文中执行的 JavaScript。内容脚本读取和修改浏览器访问的网页的 DOM。

content_script可以通过使用storage/message API来与扩展其他部分进行通信。

注入方式

// manifest.json
{
 "name": "My extension",
 ...
 "content_scripts": [
   {
     // 满足matches匹配的域名
     "matches": ["https://*.nytimes.com/*"],
     // 注入css
     "css": ["my-styles.css"],
     // 注入js
     "js": ["content-script.js"],
     "run_at": "document_idle" | "document_start" | "document_end"
   }
 ],
  "permissions": [
    "activeTab"
  ],
}

4、popup

运行于弹窗的html显示 & js脚本

// manifest.json 中引入popup.html
"action": {
     "default_title": "Click to view a popup",
   	 "default_popup": "popup.html"
 }
// popup.html 引入相关js css等
<html>
  <head>
    <meta charset="UTF-8">
    <title>京东揽才</title>
    <link rel="stylesheet" href="./css/popup.css">
    <script src="popup.js"></script>
    <script src="js/axios.min.js"></script>
  </head>
  <body>
  </body>
</html>

二、基本组成间的通信方式

JS种类可访问的APIDOM访问情况JS访问情况直接跨域
injected script和普通JS无任何差别,不能访问任何扩展API可以访问可以访问不可以
content script只能访问 extension、runtime等部分API可以访问不可以不可以
popup js可访问绝大部分API,除了devtools系列不可直接访问不可以可以
background js可访问绝大部分API,除了devtools系列不可直接访问不可以可以
devtools js只能访问 devtools、extension、runtime等部分API可以访问devtools可以访问devtools不可以

1、content script与background的通信

  • 使用 chrome.runtime.sendMessage 发送信息
  • 使用 chrome.tabs.sendMessage接收监听信息
// content_script
// 监听接收信息
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
	// 可写成switch形式 监听所有
	if (sender === "") {
		// do something
	}
	if (request.from === "cc") {
		// from 不是固定词,可使用其他自定义词汇
		// do something
	}
  // 发送回传
	sendResponse({number: request.number});

	// 修改dom
	document.querySelector("#s-usersetting-top").innerText = request.number;

	// 重发信息
	chrome.runtime.sendMessage({number: request.number + 1}, (response) => {
		console.log(
			`content script -> background infos have been received. number: ${response.number}`
		);
	});
});

// background
// 监听消息接收
chrome.runtime.onMessage.addListener((request, sender, sendResponse)=> {
	chrome.tabs.query({active: true, currentWindow: true}, (tabs)=> {
		chrome.tabs.sendMessage(tabs[0].id,{number: request.number + 1},(response) => {
				console.log(
					`background -> content script infos have been received. number: ${response.number}`
				);
		});
	});
  // 消息回传
	sendResponse({number: request.number});
});

2、popup与background的通信

// popup
document.querySelector("#button").addEventListener("click", () => {
	const val1 = document.querySelector("#input1").value || "0";
	const val2 = document.querySelector("#input2").value || "0";
	chrome.runtime.sendMessage({val1, val2}, (response) => {
		document.querySelector("#ans").innerHTML = response.res;
	});
});

// background
const dealwithBigNumber = (val1, val2) => BigInt(val1) * BigInt(val2) + "";
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
	const {val1, val2} = request;
	sendResponse({res: dealwithBigNumber(val1, val2)});
});

3、popup与content的通信

// content_script
// 接收popup数据并修改dom
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
	// document.querySelector("body").style.setProperty("background", request.color);
	$("body").css("background", request.color);
	sendResponse({name: 1});
});

chrome.tabs.query(
  {
    active: true
  },(tabs)=>{
    if (tabs.length > 0) {
      var current = tabs[0];
      chrome.tabs.sendMessage(current.id, { action: "getData"}, function (response) {
        isCanrecruit = response?response.sourceCanrecruit:null;
        showContent()
      })
    }
  });