写个 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,
  });
});

最后看一下项目结构:

效果展示

相关推荐
理想不理想v23 分钟前
vue经典前端面试题
前端·javascript·vue.js
不收藏找不到我24 分钟前
浏览器交互事件汇总
前端·交互
YBN娜37 分钟前
Vue实现登录功能
前端·javascript·vue.js
阳光开朗大男孩 = ̄ω ̄=37 分钟前
CSS——选择器、PxCook软件、盒子模型
前端·javascript·css
minDuck42 分钟前
ruoyi-vue集成tianai-captcha验证码
java·前端·vue.js
小政爱学习!1 小时前
封装axios、环境变量、api解耦、解决跨域、全局组件注入
开发语言·前端·javascript
魏大帅。1 小时前
Axios 的 responseType 属性详解及 Blob 与 ArrayBuffer 解析
前端·javascript·ajax
花花鱼1 小时前
vue3 基于element-plus进行的一个可拖动改变导航与内容区域大小的简单方法
前端·javascript·elementui
k09331 小时前
sourceTree回滚版本到某次提交
开发语言·前端·javascript
EricWang13582 小时前
[OS] 项目三-2-proc.c: exit(int status)
服务器·c语言·前端