Chrome插件开发【manifest.json】

目录

Manifest.json

常用结构

host_permissions

action

content_scripts

完整结构

options_ui

content_security_policy

homepage_url

minimum_chrome_version

incognito

web_a***essible_resources

侧边栏(side_panel)

其它


Manifest.json

本文将会从“常用结构”和“完整结构”两部分切入,分别讲解。

常用结构

{
    "manifest_version":3,
    "name":"测试插件",
    "version":"1.0",
    "description":"实现了一个测试方法",
    "icons":{
        "16":"icons/logo.png",
        "48":"icons/logo.png",
        "128":"icons/logo.png"
    },
    "action":{
        "default_popup":"popup/popup.html"
    },
    "background":{
        "service_worker":"background.js",
        "type":"module"
    },
    "content_scripts":[{
        "matches":["<all_urls>"],
        "js":["content.js"],
        "run_at":"document_end"
    }],
    "permissions":["scripting", "tabs", "storage"],
    "host_permissions":["<all_urls>"]
}
  • manifest_version[必填项]:manifest版本,必须是3(2已过期)
  • name[必填项]:插件名字
  • version[必填项]:插件版本,由您指定
  • description:插件描述
  • icon:插件图标
  • action:浏览器动作(工具栏图标)
  • permissions:权限声明
  • host_permissions:主机权限
  • content_scripts:内容脚本(注入到网页的脚本)

必填项(manifest_version、name、version)展现位置如下图所示:

浏览器动作(action)展现位置如下图所示:

host_permissions

作用

  • 允许插件与指定网站交互
    • 访问网站的DOM
    • 读取或修改网站内容
    • 注入内容脚本(content-script)
  • 启用特定API的网站访问权限
    • 使用chrome.cookies API访问指定网站的API
    • chrome.webRequest AP监控指定网站的请求
  • 跨域请求权限
    • 允许插件向指定网站发起跨域XMLHttpRequests或fetch请求

匹配语法

使用与内容脚本matches相同的模式语法

  • *”:匹配任意字符序列
  • ”:匹配任意单个字符
  • *://”:匹配所有协议(http、https等)
  • *.”:匹配所有域名
  • /*”:匹配路径下的所有内容

示例

https://example.***/    // 只匹配example.***的HTTPS
*://example.***/*    // 匹配所有协议的example.***
*://*.example.***/*    // 匹配所有子域名
http://localhost/*    // 匹配本地开发服务器

action

action可以在manifest.json文件里配置的参数只有两个:

  • default_title:鼠标悬浮提示
  • default_popup:点击插件显示的页面

content_scripts

{
  "content_scripts": [
    {
      "matches": ["https://*.example.***/*"],
      "exclude_matches": ["*://*/*admin*"],
      "css": ["content-styles.css"],
      "js": ["content-script.js"],
      "run_at": "document_idle",
      "all_frames": false,
      "match_about_blank": false
    }
  ]
}
  • matches:脚本注入的URL
  • exclude_matcher:排除不需要注入的URL
  • css:注入的CSS文件数组
  • js:注入的js文件数组
  • run_at:控制脚本注入时机
    • document_start:DOM加载前,CSS可用前
    • document_end:DOM加载后,图片等资源未加载
    • document_idle:DOMContentLaded事件后
  • all_frames:控制注入位置
    • true:注入到所有iframe
    • false(默认):只注入到顶层框架
  • match_about_blank:是否注入到about:blank页面(about:blank作为顶层页面不允许注入,在一个iframe里时允许注入)

注入的content-script是一个“半隔离”状态,具体如下:

特性 内容脚本 网页脚本
DOM访问 完全访问 完全访问
JavaScript全局对象 隔离的副本 原始对象
变量/函数共享 不共享 不共享
扩展API访问 有限访问(chrome.runtime等) 无访问

DOM是共享的

// content-script.js
document.body.style.backgroundColor = "red"; // 会影响网页和其他内容脚本

JavaScript环境是隔离的

// 网页脚本中
window.pageVar = "hello";

// 内容脚本中
console.log(window.pageVar); // ❌ 输出 undefined(无法直接访问)

完整结构

{
  "manifest_version": 3,
  "name": "My Chrome Extension",
  "version": "1.0.0",
  "description": "A sample Chrome extension using Manifest V3",
  "short_name": "My Extension",
  "version_name": "1.0 Beta",
  "icons": {
    "16": "icons/icon16.png",
    "48": "icons/icon48.png",
    "128": "icons/icon128.png"
  },
  "side_panel": {
    "default_path": "sidepanel.html",
    "openPanelOnActionClick": true,
    "matches": ["<all_urls>"]
  },
  "action": {
    "default_icon": {
      "16": "icons/icon16.png",
      "48": "icons/icon48.png"
    },
    "default_title": "My Extension",
    "default_popup": "popup.html"
  },
  "background": {
    "service_worker": "background.js"
  },
  "content_scripts": [
    {
      "matches": ["<all_urls>"],
      "js": ["contentScript.js"],
      "css": ["contentStyle.css"],
      "run_at": "document_idle"
    }
  ],
  "permissions": [
    "activeTab",
    "storage",
    "scripting",
    "tabs"
  ],
  "host_permissions": [
    "https://*/*",
    "http://*/*"
  ],
  "options_ui": {
    "page": "options.html",
    "open_in_tab": false
  },
  "content_security_policy": {
    "extension_pages": "script-src 'self'; object-src 'self'"
  },
  "homepage_url": "https://example.***",
  "minimum_chrome_version": "100.0",
  "incognito": "spanning",
  "web_a***essible_resources": [
    {
      "resources": ["images/*.png", "styles/*.css"],
      "matches": ["<all_urls>"]
    }
  ]
}

options_ui

options_ui是一个对象,包含以下常用属性:

  • page(必须):指定选项页面的HTML文件路径
  • op_in_tab(可选):布尔值,默认为false
    • false:选项页面会嵌入在Chrome的“扩展程序详情”页面中
    • true:选项页面会在新标签页打开

content_security_policy

用于限制插件可以加载和执行的资源,防止XSS等安全漏洞

  • extension_pages:表示该策略适用于插件自身的页面(popup、options)
    • script-src 'self':限制只能执行插件自身包内的脚本(不允许加载外部脚本,也不允许内联脚本)
    • object-serc 'self':限制只能加载插件自身包内的插件资源(<embed>)

homepage_url

用于指定插件的官方首页URL

  • 如不设置,默认指向该插件在Chrome应用商店的页面
  • 当用户在扩展管理页面点击“查看详情”时,会跳转到此URL(若设置)

minimum_chrome_version

指定支持该插件的最低Chrome版本

  • 若用户的Chrome版本低于此值,会在应用商店看到“不兼容”提示,且无法安装
  • 版本号可以是主版本(100)或完整版本(100.0.4896.127)

incognito

定义插件在“无痕模式”下的三个行为,支持三个值:

  • spanning(默认):插件在常规模式和无痕模式共享同一个实例,数据互通(chrome.storage等存储不会同步)
  • split:插件在无痕模式中运行独立实例,与常规模式完全隔离,数据不互通
  • not_allowd:禁止插件在无痕模式中运行

web_a***essible_resources

指定插件内部的哪些资源文件可以被外部网页(或其它插件)访问

  • resources:一个字符串数组,指定允许被外部访问的资源路径,支持通配符*匹配多个文件
  • matches:一个字符串数组,指定哪些网页可以访问这些资源

侧边栏(side_panel)

侧边栏可以通过配置manifest文件实现

{
  "manifest_version": 3,
  "name": "我的侧边栏扩展",
  "version": "1.0",
  "icons":{
    "16": "icons/logo.png",
    "48": "icons/logo.png",
    "128": "icons/logo.png"
  },
  "background":{
    "service_worker": "background.js"
  },
  "side_panel": {
    "default_path": "sidepanel.html",
    "openPanelOnActionClick": true
  },
  "action": {
    "default_title": "打开侧边栏"
  },
  "permissions": ["sidePanel"]
}

如需用户点击插件图标开关侧边栏,可以在background.js文件中添加如下代码:

chrome.sidePanel
    .setPanelBehavior({ openPanelOnActionClick: true })
    .catch((error) => console.error(error));

其它

更多Chrome插件开发学习,可以参考我的专栏:

Chrome插件_是洋洋a的博客-CSDN博客

转载请说明出处内容投诉
CSS教程网 » Chrome插件开发【manifest.json】

发表评论

欢迎 访客 发表评论

一个令你着迷的主题!

查看演示 官网购买