FunTester Chrome 扩展程开发初探

FunTester · 2024年07月22日 · 2860 次阅读

最近学习了一些前端知识,准备找点方向和项目在工作之余练练手。偶然间被 ChatGPT 提醒,觉得 Chrome 拓展开发是一个非常不错的方向。

Chrome 拓展是扩展浏览器功能的小程序,用户可以通过 Chrome Web Store 下载和安装。这些拓展能够增强浏览器的性能和用户体验,例如广告拦截、实时翻译、任务管理、笔记记录等。插件还提供自定义功能,使用户能够根据个人喜好调整浏览器外观和书签管理。同时,安全插件可以保护用户隐私和数据安全,开发拓展帮助开发者更高效地调试代码。跨平台同步功能使得用户可以在不同设备上享有一致的浏览体验。Chrome 应用市场丰富多样,满足各种需求。

优势

在我看来,Chrome 拓展有一下几点好处:

  1. 操作简单快捷。相比较普通的Web页面,拓展可以更快直达用户,免去跳转切换的繁琐手续。配合快捷键更是如虎添翼,直上云霄。
  2. 开发成本低。Chrome 拓展开发只需要创建符合Chrome要求的目录即可。简单的一键式直达功能不需要工程化,直接一两个方法解决。前端代码完全可以比照Web端编写,甚至代码拿来即用,兼容性非常好。
  3. 开发效率高。据我自己体验,Chrome 拓展的页面相对简单和独立,对于大量功能性页面,不需要太多交互设计,大大降低了开发难度,提升开发效率。对于一个前端小白的我来说,跟 ChatGPT 对话就能完成类似 Postman 单页面的开发。甚至还能微调 CSS 提升美观程度。

还有一个不咋上的台面的原因,就是可以直接抄别人的代码。比如我需要内置一个历史页面的管理功能,直接去 Chrome 商店下载一个拓展,然后发动抄能力,把源码抄过来即可,直呼过瘾。我已经在实践项目中抄了 3 个别人插件的源码,其中复活了一个由于未及时适配 Manifest V3 而被下架的插件,功能就是防止浏览器窗口关闭最后一个标签时会关闭整个窗口,有兴趣的可以私聊发源码交流。

下面正式进入正题,如何开发 Chrome 拓展。

准备

首先你需要具备一些知识:HTMLCSSJavaScript 等。
其次需要了解 Chrome 拓展开发规范和 API。
最后你需要一件趁手的兵器,我用的 Webstorm

第一步

首先需要一个 manifest.json 文件。manifest.json 文件是 Chrome 扩展的配置文件,定义了扩展的基本信息、权限和功能。下面是一个简单的示例:

{
  "manifest_version": 3,
  "name": "FunTester Extension",
  "version": "1.0",
  "description": "This is a simple Chrome extension example.",
  "icons": {
    "48": "icon48.png",
    "128": "icon128.png"
  },
  "permissions": [
    "tabs",
    "storage"
  ],
  "background": {
    "service_worker": "background.js"
  },
  "action": {
    "default_popup": "popup.html",
    "default_icon": "icon48.png"
  },
  "content_scripts": [
    {
      "matches": ["<all_urls>"],
      "js": ["content.js"]
    }
  ],
  "web_accessible_resources": [
    {
      "resources": ["content.js"],
      "matches": ["<all_urls>"]
    }
  ]
}

以下是其主要功能的简介:

  1. 基本信息
    • manifest_version:指定清单文件的版本,目前最新版本是 3。
    • name:扩展的名称。
    • version:扩展的版本号。
    • description:扩展的简短描述。
    • icons:定义扩展的图标,可以指定不同尺寸的图标。
  2. 权限
    • permissions:列出扩展需要的权限,例如访问标签页、存储等。这决定了扩展可以访问的浏览器功能和用户数据。
  3. 后台脚本
    • background:定义后台脚本,在 manifest_version 3 中使用 service_worker。后台脚本在浏览器启动时运行,管理扩展的生命周期和处理事件。
  4. 浏览器动作
    • action:定义扩展图标的默认行为,如点击图标时弹出的页面(popup),可以设置默认弹出页面和图标。
  5. 内容脚本
    • content_scripts:定义内容脚本,这些脚本将注入到匹配的网页中运行。内容脚本可以修改网页内容或监听网页事件。
  6. 可访问资源
    • web_accessible_resources:定义扩展中可以被网页访问的资源,例如内容脚本或图标。这使得网页能够访问扩展内的特定文件。

通过配置 manifest.json 文件,可以定义和控制 Chrome 扩展的各种功能和行为,包括用户界面、后台处理、网页内容修改和权限管理。这使得开发者能够创建功能丰富且安全的浏览器扩展。

以上信息建议去官方查看,我就是因为版本 V2 教程耽误了好一阵子功夫。

常用功能

在 Chrome 扩展中,popup 页面是指当用户点击扩展图标时弹出的界面。这个界面通常用于提供用户交互或展示信息。Popup 页面由一个 HTML 文件组成,可以包含 JavaScript 和 CSS 来实现其功能和样式。

popup 页面配置方式如下:

{
  "manifest_version": 3,
  "name": "FunTester Extension",
  "version": "1.0",
  "description": "This is a simple Chrome extension example.",
  "action": {
    "default_popup": "popup.html",
    "default_icon": "icon48.png"
  },
  // 其他配置项...
}

这是一个简单的 popup 页面:

<!DOCTYPE html>
<html>
<head>
  <title>Popup</title>
  <style>
    body {
      width: 300px;
      height: 200px;
      font-family: Arial, sans-serif;
      padding: 10px;
    }
    button {
      margin-top: 20px;
    }
  </style>
</head>
<body>
  <h1>Hello, World!</h1>
  <p>This is a simple popup example.</p>
  <button id="myButton">Click me</button>

  <script src="popup.js"></script>
</body>
</html>

不清楚是什么版本开始,或者一直就这样。Chrome 扩展的安全性设计确实不允许在 HTML 页面中直接使用 JavaScript 代码来加载或执行扩展的功能。Chrome 扩展通过内容安全性策略来限制可以在页面上执行的脚本。这意味着扩展不能简单地通过内联 <script> 标签或通过 document.write() 插入的脚本来执行。这是为了防止恶意代码的执行和保护用户的安全。所以都是写在另外的 js 文件当中。

假如我们想给这个 myButton 添加一个 onClick 事件的处理方法,可以在 popup.js 中添加下面的代码:

document.addEventListener('DOMContentLoaded', function() {
  document.getElementById('myButton').addEventListener('click', function() {
    alert('Button clicked!');
  });
});

background

background.js 文件是 Chrome 扩展的后台脚本,用于处理长期运行的任务、事件和状态管理。它在浏览器的后台运行,并且在浏览器启动时加载。对于 manifest_version 3,使用 service_worker 作为后台脚本。

下面是配置方法:

{
  "manifest_version": 3,
  "background": {
    "service_worker": "background.js"
  },
  // 其他配置项...
}

而在 V2 当中是这么配置的:

{
  "manifest_version": 2,
  "background": {
    "scripts": ["background.js"],
    "persistent": false
  },
  // 其他配置项...
}

顾名思义,background.js 就是作为背景存在,无论当我们在哪个页面上都会被加载。在 manifest_version 3 中,通过在 manifest.json 文件中定义 background 部分并引用 background.js 作为服务工作者,可以配置后台脚本来处理扩展的安装事件、消息传递、浏览器事件监听、持久存储、定时任务和网络请求。通过这种方式,可以在后台脚本中实现复杂的逻辑和状态管理,同时与其他扩展组件进行通信。

下面是 background.js 主要的功能演示:

1. 处理安装事件

在扩展安装或更新时执行一些初始化操作:

chrome.runtime.onInstalled.addListener((details) => {
  if (details.reason === 'install') {
    console.log("Extension installed");
    // 初始化一些数据
    chrome.storage.local.set({initialized: true});
  } else if (details.reason === 'update') {
    console.log("Extension updated to version " + chrome.runtime.getManifest().version);
  }
});

2. 消息传递

监听和处理来自内容脚本(content scripts)、弹出页面(popup)和其他部分的消息:

chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
  if (message.type === "GREETINGS") {
    console.log("Received message from", sender.tab ? "content script" : "popup", ":", message.payload);
    sendResponse({message: "Hello from background script"});
  }
});

3. 浏览器事件监听

监听浏览器的各种事件,例如标签页更新:

chrome.tabs.onUpdated.addListener((tabId, changeInfo, tab) => {
  if (changeInfo.status === 'complete') {
    console.log("Tab updated: ", tabId);
    // 在更新的标签页中执行一些操作
  }
});

4. 持久存储和同步

使用 Chrome 存储 API 在浏览器关闭时保持数据持久化:

// 存储数据
chrome.storage.local.set({key: 'value'}, () => {
  console.log('Value is set to value');
});

// 获取数据
chrome.storage.local.get(['key'], (result) => {
  console.log('Value currently is ' + result.key);
});

我们还可以将数据存储到云端,方便跨设备同步:

// 存储数据到同步存储
chrome.storage.sync.set({key: 'value'}, () => {
  console.log('Value is set to value');
});

// 获取同步存储中的数据
chrome.storage.sync.get(['key'], (result) => {
  console.log('Value currently is ' + result.key);
});

// 删除同步存储中的数据
chrome.storage.sync.remove(['key'], () => {
  console.log('Value is removed');
});

// 清空所有同步存储数据
chrome.storage.sync.clear(() => {
  console.log('All sync storage data is cleared');
});

5. 定时任务

设置定时器来定期执行任务:

setInterval(() => {
  console.log("Periodic task running...");
  // 执行定期任务
}, 60000); // 每分钟运行一次

6. 网络请求

发起网络请求,处理数据,并与服务器通信:

function fetchData() {
  fetch('https://api.example.com/data')
    .then(response => response.json())
    .then(data => console.log(data))
    .catch(error => console.error('Error fetching data:', error));
}

// 定期获取数据
setInterval(fetchData, 3600000); // 每小时运行一次

content_scripts

Chrome 扩展中,content.js 是内容脚本,用于在匹配的网页上执行 JavaScript 代码。内容脚本可以修改网页的 DOM 结构,与页面进行交互,并在浏览器页面加载时注入执行。

配置方法如下:

{
  "manifest_version": 3,
  "content_scripts": [
    {
      "matches": ["<all_urls>"],
      "js": ["content.js"]
    }
  ]
}

假如我想在页面 body 中添加一个元素,可以在 content.js 中添加以下代码:

console.log("Content script loaded");

// 在页面 DOM 加载完成后执行操作
document.addEventListener('DOMContentLoaded', function() {
  // 在页面中插入一个 div 元素
  const div = document.createElement('div');
  div.textContent = 'This content is injected by Chrome extension.';
  document.body.appendChild(div);
});

Chrome 扩展中的 content.js 主要功能包括:

  1. DOM 操作:修改页面的 DOM 结构,例如插入、删除或修改元素。
  2. 事件监听:监听页面上的各种事件,如点击、输入、滚动等,以响应用户操作。
  3. 与页面交互:与页面上的元素进行交互,获取或修改它们的内容、属性和样式。
  4. 数据注入:在页面加载时向页面注入自定义的 HTML、CSS 或 JavaScript,改变页面的外观或行为。
  5. 内容修改和过滤:根据特定规则修改页面内容,过滤广告、隐藏特定元素或修改网页样式。
  6. 消息传递:与扩展的其他部分(如后台脚本 background.js、弹出页面 popup.js)进行消息传递和通信。
  7. 数据采集和分析:收集页面上的数据,进行分析或发送到后台进行处理。
  8. 页面状态监控:监控页面的加载状态和变化,执行相应的操作或显示加载状态。
  9. 与第三方服务集成:与网页上的第三方服务或 API 进行集成和交互,获取数据或执行操作。

右键菜单

Chrome 扩展中,右键菜单(Context Menu)是指用户右键点击浏览器页面或特定元素时弹出的菜单选项。开发者可以通过 Chrome 扩展来添加自定义的右键菜单选项,以提供更多的功能和交互性。

若想使用,需要在权限当中添加 contextMenus 内容,如下:

  "permissions": [
    "contextMenus"
  ],

我们通常会把创建右键菜单的方法放到 background 当中,这样就能一直运行。下面是添加右键菜单以及监听时间的代码演示:

// 创建一个右键菜单项
chrome.contextMenus.create({
  id: "myContextMenu",
  title: "Do Something",
  contexts: ["page", "selection", "link"]
});

// 监听右键菜单点击事件
chrome.contextMenus.onClicked.addListener((info, tab) => {
  if (info.menuItemId === "myContextMenu") {
    console.log("Context menu item clicked:", info);
    // 执行相应的操作,例如发送消息到 content script 或执行后台任务
  }
});

使用 chrome.contextMenus.create 方法创建右键菜单项。使用 chrome.contextMenus.onClicked 监听菜单项点击事件。

如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
暂无回复。
需要 登录 后方可回复, 如果你还没有账号请点击这里 注册