背景
平时工作中经常会遇到需要格式化 JSON 查看数据的情况,以前收藏了一个网址用来格式化 JSON 很方便,最近广告越来越多,每次打开都有弹窗广告,烦不胜烦。虽然复制粘贴到编辑器再 Format 可以解决问题,但是比较麻烦,干脆自己写个 Chrome 扩展程序来解决问题。
创建第一个 Chrome 扩展程序
创建
创建 Chrome 扩展程序(或者说 Chrome 插件)其实很简单,我们先创建一个最基础的扩展程序来演示,当用户点击扩展工具栏图标时,该扩展将显示 "Hello Extensions"。
首先,我们新建一个文件夹,我给他命名为 hello-world,并在根目录创建 manifest.json
配置文件:
{
"manifest_version": 3,
"name": "Hello Extensions",
"description": "Base Level Extension",
"version": "1.0",
"action": {
"default_popup": "hello.html",
"default_icon": "hello_extensions.png"
}
}
其中 "default_icon": "hello_extensions.png"
指定了图标文件,需要在文件夹添加名为 hello_extensions.png
图片,作为扩展程序的图标。
最后创建 hello.html
文件。
<html>
<body>
<h1>Hello Extensions</h1>
</body>
</html>
此时我们的文件夹有如下三个文件:
这样一个简单的扩展程序就完成了,现在需要在 Chrome 加载它。
加载
打开 chrome://extensions ,按下图先打开“开发者模式”,然后点击“加载已解压的扩展程序”来加载我们刚才创建的扩展程序文件夹(我的为 hello-world) 。
现在可以在打开新页面后,在扩展程序中找到我们新创建的 "Hello Extensions" 了,可以点击 “图钉” 图标将扩展固定在 Tab 上。
点击扩展程序的图标,可以看到弹出了 "Hello Extensions"。
刷新
现在尝试修改 manifest.json
中的 name
,然后在扩展程序管理中刷新,可以看到扩展程序的名字发生了变化。
{
"manifest_version": 3,
"name": "Hello World",
// ...
}
manifest.json
在 Chrome 扩展开发中,manifest.json
是必须包含的文件。它是一个 JSON 格式的文件,包含了 Chrome 扩展的元数据和配置信息。Chrome 浏览器通过解析这个文件来了解如何加载和管理插件。以下是 manifest.json
文件中可能包含的一些重要字段及其作用:
manifest_version
:指定 manifest 文件的版本,目前的版本为 3。name
:插件的名称。version
:插件的版本号。description
:对插件功能的简短描述。icons
:插件的图标,可以在不同的上下文中使用,比如扩展栏、扩展管理页面等。permissions
:插件请求的权限列表,如访问标签页、使用cookies、访问特定网站的数据等。host_permissions
:列出扩展可以访问的网站。action
:用于定义扩展在浏览器工具栏中的按钮及其行为。background
:service_worker
:指定扩展的后台服务工作线程。Manifest V3不再支持长时间运行的后台页面,而是使用服务工作线程。
content_scripts
:指定插件将注入到网页中的脚本,以及这些脚本应当在哪些网页上运行。options_ui
:page
:定义扩展的选项页面。open_in_tab
:布尔值,指定选项页面是否在新标签页中打开。
content_security_policy
:extension_pages
:定义了扩展页面的内容安全策略。
web_accessible_resources
:resources
:列出了哪些资源可以被网页内容访问。extension_ids
:指定哪些扩展可以访问这些资源。
declarativeNetRequest
:rule_resources
:定义了扩展声明性网络请求规则的资源。
commands
:定义插件的快捷键命令。
JSON 编辑器
学会了创建扩展程序,接下来开始正题。格式化 JSON 前需要先找一个 JSON 编辑器。我选择了 jsoneditor,
接下来简单写个 JSON 格式化的页面:
- HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>JSON格式化</title>
<link rel="stylesheet" href="./index.css" />
<!-- <script src="https://cdnjs.cloudflare.com/ajax/libs/jsoneditor/9.10.4/jsoneditor.min.js"></script> -->
<!-- <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jsoneditor/9.10.4/jsoneditor.min.css" /> -->
<script src="../lib/jsoneditor.min.js"></script>
<link rel="stylesheet" href="../lib/jsoneditor.min.css" />
</head>
<body>
<div class="container">
<textarea type="textarea" id="input" class="source"> </textarea>
<div id="jsoneditor" class="target"></div>
</div>
<script src="./index.js"></script>
</body>
</html>
- JavaScript
const container = document.getElementById("jsoneditor");
const errorMsg = document.getElementById("errorMsg");
const input = document.getElementById("input");
const options = {
modes: ["code", "form", "tree"],
onChangeText(text) {
try {
const json = JSON.parse(text);
input.value = JSON.stringify(json, null, 4);
} catch (e) {}
},
showErrorTable: true,
};
const editor = new JSONEditor(container, options, "");
input.addEventListener("input", (event) => {
const text = event.target.value;
if (!text) {
editor.set();
editor.container.className = "target";
return;
}
try {
const json = JSON.parse(text);
editor.set(json);
editor.container.className = "target";
} catch (e) {
editor.set(e.message);
editor.container.className = "target error-status";
}
});
- CSS
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
html,
body {
height: 100%;
}
.container {
display: flex;
flex-direction: row;
font-family: menlo, "monospace", Tahoma, 微软雅黑, 幼圆 !important;
height: 100%;
padding: 20px;
position: relative;
}
.source {
flex: 45% 0 0;
margin-right: 10px;
padding: 10px 10px 10px 30px;
border: 0;
border-radius: 0;
resize: none;
outline: none;
border: 1px solid #d8d8d8;
border-radius: 5px;
font-size: 16px;
}
.target {
flex: 1;
}
/* JSON编辑器菜单 */
div.jsoneditor,
div.jsoneditor-menu {
border-color: #35cca2;
}
div.jsoneditor-menu {
background-color: #35cca2;
}
/* JSON编辑器代码颜色 */
.ace-jsoneditor .ace_variable {
color: #92278f;
font-weight: bold;
}
.ace-jsoneditor .ace_string {
color: #3ab54a;
font-weight: bold;
}
.ace-jsoneditor .ace_constant.ace_numeric {
color: #25aae2;
font-weight: bold;
}
/* 输入不合法JSON的情况下 */
.error-status .ace_constant, .error-status .ace_string {
color: #f1592a;
font-weight: bold;
}
页面效果(我承认我借(chao)鉴(xi)了某个 JSON 网站:
左边是我们贴进去的字符串,右边是格式化后的 JSON。左边或右边编辑的时候,另一边也会同步修改,当 JSON 格式错误时,也会展示对应的错误信息。
其中用到了 jsoneditor 的资源,因为直接在扩展程序打开遇到了跨域的错误,所以我复制了一份到本地。
扩展程序中打开页面
页面已经写好了,可以开始写扩展程序了。
新建一个 json-formatter
文件夹,然后创建 manifest.json
文件:
{
"manifest_version": 3,
"name": "JSON Formatter",
"description": "JSON Formatter",
"version": "1.0",
"background": {
"service_worker": "background.js"
},
"permissions": ["scripting"],
"action": {
"default_icon": "json.jpg"
}
}
其中 background.service_worker
指定了扩展程序的脚本文件,我们只需要在这里实现一件事,就是在点击扩展程序的时候,打开 JSON 编辑页面:
chrome.action.onClicked.addListener(function (activeTab) {
chrome.tabs.create({
url: "./json-editor/index.html",
selected: true,
active: true,
});
});
最后看一下项目结构: