写个 Chrome 扩展程序来 JSON 格式化

背景

平时工作中经常会遇到需要格式化 JSON 查看数据的情况,以前收藏了一个网址用来格式化 JSON 很方便,最近广告越来越多,每次打开都有弹窗广告,烦不胜烦。虽然复制粘贴到编辑器再 Format 可以解决问题,但是比较麻烦,干脆自己写个 Chrome 扩展程序来解决问题。

创建第一个 Chrome 扩展程序

创建

创建 Chrome 扩展程序(或者说 Chrome 插件)其实很简单,我们先创建一个最基础的扩展程序来演示,当用户点击扩展工具栏图标时,该扩展将显示 "Hello Extensions"。

首先,我们新建一个文件夹,我给他命名为 hello-world,并在根目录创建 manifest.json 配置文件:

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 复制代码
<html>
  <body>
    <h1>Hello Extensions</h1>
  </body>
</html>

此时我们的文件夹有如下三个文件:

这样一个简单的扩展程序就完成了,现在需要在 Chrome 加载它。

加载

打开 chrome://extensions ,按下图先打开"开发者模式",然后点击"加载已解压的扩展程序"来加载我们刚才创建的扩展程序文件夹(我的为 hello-world) 。

现在可以在打开新页面后,在扩展程序中找到我们新创建的 "Hello Extensions" 了,可以点击 "图钉" 图标将扩展固定在 Tab 上。

点击扩展程序的图标,可以看到弹出了 "Hello Extensions"。

刷新

现在尝试修改 manifest.json 中的 name,然后在扩展程序管理中刷新,可以看到扩展程序的名字发生了变化。

json 复制代码
{
  "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
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
js 复制代码
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
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 文件:

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 编辑页面:

js 复制代码
chrome.action.onClicked.addListener(function (activeTab) {
  chrome.tabs.create({
    url: "./json-editor/index.html",
    selected: true,
    active: true,
  });
});

最后看一下项目结构:

效果展示

相关推荐
sg_knight7 分钟前
VSCode如何修改默认扩展路径和用户文件夹目录到D盘
前端·ide·vscode·编辑器·web
一个处女座的程序猿O(∩_∩)O16 分钟前
完成第一个 Vue3.2 项目后,这是我的技术总结
前端·vue.js
mubeibeinv17 分钟前
项目搭建+图片(添加+图片)
java·服务器·前端
逆旅行天涯23 分钟前
【Threejs】从零开始(六)--GUI调试开发3D效果
前端·javascript·3d
m0_7482552644 分钟前
easyExcel导出大数据量EXCEL文件,前端实现进度条或者遮罩层
前端·excel
web147862107231 小时前
C# .Net Web 路由相关配置
前端·c#·.net
m0_748247801 小时前
Flutter Intl包使用指南:实现国际化和本地化
前端·javascript·flutter
飞的肖1 小时前
前端使用 Element Plus架构vue3.0实现图片拖拉拽,后等比压缩,上传到Spring Boot后端
前端·spring boot·架构
青灯文案11 小时前
前端 HTTP 请求由 Nginx 反向代理和 API 网关到后端服务的流程
前端·nginx·http
m0_748254882 小时前
DataX3.0+DataX-Web部署分布式可视化ETL系统
前端·分布式·etl