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

前景

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

开始开发

清单文件(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的父文件夹)

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

相关推荐
Beekeeper&&P...30 分钟前
AddressBookController
java·前端·网络
今天也要暴富34 分钟前
CSS Grid 布局:属性及使用详解
前端·css
前端熊猫39 分钟前
组件十大传值
前端·javascript·vue.js
oumae-kumiko1 小时前
【JS/TS鼠标气泡跟随】文本提示 / 操作提示
前端·javascript·typescript
YG·玉方1 小时前
键盘常见键的keyCode和对应的键名
前端·javascript·计算机外设
梦屿千寻!!1 小时前
Axios和Ajax的区别
前端
iOS开发的小学生1 小时前
鸿蒙app封装 axios post请求失败问题
前端·harmonyos·鸿蒙开发
我码玄黄2 小时前
在THREEJS中加载3dtile模型
前端·javascript·3d·threejs
文浩(楠搏万)2 小时前
Java Spring Boot 项目中嵌入前端静态资源:完整教程与实战案例
java·服务器·前端·spring boot·后端·nginx·github
悠悠华2 小时前
使用layui的table提示Could not parse as expression(踩坑记录)
前端·javascript·layui