三分钟学会开发一个谷歌插件!

前景

由于公司的项目用到了国密加密,而且又是使用内网开发,导致接口开发后返回的数据为加密后的值,返回参数必须复制出来,然后调用根据类去解密参数,而且解密后的参数没有格式化也不美观,就琢磨着为什么不自己写一个工具,复制值进去就自动解析解放生产力

开始开发

清单文件(manifest.json)

首先在插件根目录插件一个清单文件 manifest.json

json 复制代码
{
  "manifest_version": 3,
  "name": "国密解密",
  "version": "1.0",
  "description": "对国密内容进行解密",
  "action": {
    "default_icon": {
      "16": "icon16.png",
      "48": "icon48.png",
      "128": "icon128.png"
    },
    "default_title": "跳转插件页面"
  },
  "background": {
    "service_worker": "background.js"
  },
  "permissions": ["tabs"]
}
  1. manifest_version 用于指定扩展程序使用的清单文件格式版本,固定写3即可
  2. name 插件名称
  3. action.default_icon 插件图标
  4. action.default_title 鼠标hover的时候提示的文案
  5. background.service_worker 控制的js文件,插件安装成功执行background.js中的代码

background.js

manifest.json 同级创建background.js文件

JavaScript 复制代码
chrome.action.onClicked.addListener(() => {
    // 使用 chrome.runtime.getURL 获取插件内部页面的URL
    const internalPageUrl = chrome.runtime.getURL("./src/index.html");

    // 在新标签页中打开插件页面
    chrome.tabs.create({ url: internalPageUrl });
});

监听点击插件后,去根据相对路径去得到绝对地址并打开地址
./src/index.html这就是我们的打包后的产物

开始我们愉快的开发

首先检查我们的 manifest.jsonbackground.js 以及 src 目录的创建

然后我们创建一个正常的vue3项目

主要就用到四个包

  1. element-plus 负责界面的表单内容
  2. jsoneditor 格式化我们解密后的内容,美观输出到界面,方便查看
  3. sm-crypto 加密/解密的包,我们会使用到其中的 sm4
  4. @types/sm-cryptosm-crypto增加语法提示

解密部分代码

html 复制代码
<script setup lang="ts">
import {onMounted, ref} from "vue";
// @ts-ignore
import JSONEditor from 'jsoneditor'
import 'jsoneditor/dist/jsoneditor.min.css'
import 'jsoneditor/dist/jsoneditor.min.js'
import {ElMessage} from "element-plus";
import { sm4 } from "sm-crypto"

const key = ref('')
const iv = ref('')
const padding = ref<'pkcs#7'|'pkcs#5'>('pkcs#7')
const signText = ref('')

const jsonEditor = ref()
const editor = ref<any>()
const onSubmit = () => {
  if(!signText.value) return ElMessage.error('请输入待解密的数据')
  if(!key.value) return ElMessage.error('请输入key')
  if(!iv.value) return ElMessage.error('请输入iv')
  try {
    const data = sm4.decrypt(signText.value, key.value, { iv: iv.value, mode: 'cbc', padding: padding.value })
    if(data == '') throw new Error('解密内容失败,请检查是否为正确的加密内容')
    console.log(data)
    editor.value.set(data)
  } catch (e: any) {
    ElMessage.error(e.message)
  }
}

onMounted(() => {
  editor.value = new JSONEditor(jsonEditor.value, { mode: 'code' }, "");

  const localKey = localStorage.getItem('sm4_key')
  const localIv = localStorage.getItem('sm4_iv')
  const localPadding = localStorage.getItem('sm4_padding')
  if(localKey) key.value = localKey
  if(localIv) iv.value = localIv
  if(localPadding) padding.value = localPadding as any

  window.addEventListener('beforeunload', () => {
    if(key.value) localStorage.setItem('sm4_key', key.value)
    if(iv.value) localStorage.setItem('sm4_iv', iv.value)
    if(padding.value) localStorage.setItem('sm4_padding', padding.value)
  })
})
</script>

<template>
  <div class="page">
    <div style="flex: 1; overflow: hidden;border: solid 1px #ddd; padding: 20px; box-sizing: border-box;">
      <el-form label-width="auto" style="width: 100%">
        <el-form-item label="key">
          <el-input v-model="key" placeholder="请输入key" />
        </el-form-item>
        <el-form-item label="iv">
          <el-input v-model="iv" placeholder="请输入iv" />
        </el-form-item>
        <el-form-item label="填充模式">
          <el-select v-model="padding" placeholder="请选择填充模式">
            <el-option key="pkcs#7" label="pkcs#7" value="pkcs#7" />
            <el-option key="pkcs#5" label="pkcs#5" value="pkcs#5" />
          </el-select>
        </el-form-item>
        <el-form-item label="加密内容">
          <el-input v-model="signText" placeholder="请输入加密内容" type="textarea" :autosize="{ minRows: 4, maxRows: 8 }" />
        </el-form-item>
        <el-form-item>
          <el-button type="primary" @click="onSubmit">解密</el-button>
        </el-form-item>
      </el-form>
    </div>
    <div style="width: 60%; overflow: hidden;border: solid 1px #ddd; margin-left: 10px;">
      <div ref="jsonEditor" class="target" style="height: 95vh"></div>
    </div>
  </div>
</template>

<style scoped>
.page {
  width: 100vw;
  height: 100vh;
  display: flex;
}
.read-the-docs {
  color: #888;
}
</style>

打包安装插件

首先我们运行一遍pnpm run build打包一下完成后的开发界面 要注意:默认打包后的路径为绝对路径,可以通过vite.config.ts去修改打包为相对路径,在这里为了省事我们直接改为相对路径即可。

打包后将打包产物移到src中

我们的结构应如图所示

然后我们打开链接chrome://extensions/,进入后我们打开开发者模式,加载已解压程序,直接选择我们的开发根目录对应的文件夹即可(manifest.json的父文件夹)

然后我们就可以愉快的使用我们的插件了

相关推荐
崔庆才丨静觅11 小时前
hCaptcha 验证码图像识别 API 对接教程
前端
passerby606111 小时前
完成前端时间处理的另一块版图
前端·github·web components
掘了11 小时前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
崔庆才丨静觅12 小时前
实用免费的 Short URL 短链接 API 对接说明
前端
崔庆才丨静觅12 小时前
5分钟快速搭建 AI 平台并用它赚钱!
前端
崔庆才丨静觅12 小时前
比官方便宜一半以上!Midjourney API 申请及使用
前端
Moment12 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端
崔庆才丨静觅13 小时前
刷屏全网的“nano-banana”API接入指南!0.1元/张量产高清创意图,开发者必藏
前端
剪刀石头布啊13 小时前
jwt介绍
前端
爱敲代码的小鱼13 小时前
AJAX(异步交互的技术来实现从服务端中获取数据):
前端·javascript·ajax