手把手教你写自定义的chrome浏览器插件之———二维码生成器

撸代码,就是用代码的方式简化操作,更好的解决问题。有了需求,才有了撸代码的动力。所以本文主要按照提出问题->解决问题这一方式来阐述

提出问题

我们在启动vue/react的项目时,启动好的项目地址一般是类似http://localhost:8080/*等。有些项目中设置了自动打开浏览器,有些项目中需要手动复制地址到浏览器中打开。总之,我们可以上述的地址来访问我们的项目。

但是如果我们的项目是一个h5的项目,如何在手机上打开我们的项目呢?做过h5项目的都知道,我们可以通过将我们的上述地址生成一个二维码,手机可以扫描二维码来访问项目。好了,手机扫描了二维码发现页面空白,为啥呢?原来我们手机上不知道这个localhost到底是啥?怎么解决呢?我们可以在终端查看我们的ip,查找到ip后将localhost替换为ip,重新生成二维码,再次扫描,这次终于成功了。

上面的步骤好繁琐,如何简化我们的步骤呢?所以,我们的问题就是:如何能开发一个浏览器的插件,可以将当前的网址生成一个二维码,此外,如果当前的网址中包含了localhost,要将localhost替换成本机的ip

所以,我们主要解决两个问题

  • 可以生成二维码的chrome的插件
  • 将localhost替换成本机ip

解决问题

获取本机的ip

项目地址

主要是用了node模块中的os.networkInterfaces(),这个函数返回了很多的值,我们主要是用的是en0,具体的参数详解可以自己查一下

核心代码:

app.js

ini 复制代码
const Koa = require('koa');
const Router = require('koa-router');
const bodyParser = require('koa-bodyparser');
const cors = require('@koa/cors');
const IPRoutes = require('./routes/ipRoute');

const app = new Koa();
// 加载 cors 中间件
app.use(cors());

app.use(bodyParser());
app.use(IPRoutes.routes());
app.use(IPRoutes.allowedMethods());

app.listen(7267, () => {
    console.log('应用已经启动,http://localhost:7267');
})

module.exports = app;

/routes/ipRoute.js

arduino 复制代码
const Router = require("koa-router");
const { home, getCurrentIp } = require("../controllers/ipController.js");
// 创建一个 router 实例
const router = new Router();
// 获取ip的接口
router.get("/getCurrentIp", getCurrentIp);
router.get('/', home)

module.exports = router;

/controllers/ipController

ini 复制代码
const os = require('os');
exports.getCurrentIp = async (ctx) => {
    try {
        // 默认访问以太网
        const { type } = ctx.request.query || 'en0'
        const interfaces = await os.networkInterfaces();
        // 测试
        ctx.body = {
            data: interfaces[type]
        }
    } catch (e) {
        ctx.body = []
    }
}
exports.home = (ctx) => {
    ctx.body = '接口ok'
}

二维码生成器插件

关于chrome的插件,我之前写过一篇文章:!如何实现掘金复制自由-从0到1搭建chrome插件,这里就不详细的介绍,主要分析一下需求

  • 需要一个文本框,显示当前的url,获取当前页面的url,需要用到chrome的tabs的权限
  • 将url生成二维码

下面直接贴一下核心代码:

项目地址

manifest.json

json 复制代码
{
    "name":"generate-code-pic",  
    "version":"1.0",       
    "description":"generate code picture",  
    "manifest_version":3,
    "icons":{
        "32": "images/icon_32.png",
        "48": "images/icon_48.png",
        "64": "images/icon_48.png"
    },
    "permissions": ["tabs"],
    "action":{
        "default_popup": "popup.html"
    }
}

popup.html

xml 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>二维码生成器</title>
    <link rel="stylesheet" href="./popup.css">
</head>
<body>
    <div class="wrap">
        <div class="img">
            <div id="qrcode" class="qrcode"></div>
        </div>
        <div>
            <p>域名:</p>
            <div type="text" id="ipt" class="ipt"></div>
        </div>
    </div>  
</body>
// 用来生成二维码的插件,可以网上下载到本地
<script src="./qrcode.min.js"></script>
<script src="./popup.js"></script>
</html>

popup.js

javascript 复制代码
const getLocalIP = async () => {
  try {
      const url = 'http://localhost:7267/getCurrentIp?type=en0'
      const response = await fetch(url);
      return response.json()
  } catch (e) {
      return null
  }
}

const handleFn = async ()=>{
  const { data = [] } = await getLocalIP() || {};
    let ip = ''
    if (data?.length) {
        for (let i = 0; i < data.length; i++) {
            const item = data[i]
            const reg = /^\d{1,3}.\d{1,3}.\d{1,3}.\d{1,3}$/
            if (reg.test(item.address)) {
                ip = item.address
                return ip
            }
        }
    }
    return ip
}
  
chrome.tabs.query({active: true, currentWindow: true}, async function(tabs) {
    if (tabs.length > 0) {
      const currentTab = tabs[0];
      const currentURL = currentTab.url;
      const ipt = document.getElementById('ipt')
      let finalUrl = currentURL
      if(finalUrl.includes('localhost')){
        const ip = await handleFn() 
        finalUrl = finalUrl.replace('localhost',ip)
      }
      ipt.innerHTML = finalUrl
      new QRCode(document.getElementById("qrcode"), {
        text: finalUrl, // 设置要生成二维码的链接
        width: 200, // 设置二维码的宽度
        height: 200, // 设置二维码的高度
        colorDark : "#000000", // 设置二维码的前景色
        colorLight : "#ffffff", // 设置二维码的背景色
        correctLevel : QRCode.CorrectLevel.H // 设置二维码的纠错级别
      });
    }
});

验证

  • 启动get-ip的服务,进入项目后执行npm run serve

  • 在浏览器中加载插件

可以看到我们想要的已经实现了,但是每次都要手动进入get-ip的项目,有点麻烦,能不能一键启动呢,所以,这里就需要一个优化

优化

(以下的操作仅限于mac,window平台需要自行查阅一下差异)

  • 在桌面新建一个.command的文件
  • 文件内容
bash 复制代码
#!/bin/bash
cd /Users/ldyjjm/study/get-ip
npm run serve
  • 给.command文件权限
bash 复制代码
chmod +x ~/Desktop/build.command
  • 双击文件运行

再运行下我们的项目,看下浏览器插件正常工作,完结

相关推荐
魔法少女樱几秒前
如何在idea中写spark程序
前端·javascript·ajax
三思而后行,慎承诺2 分钟前
npm、pnpm 和 yarn 包管理工具
前端·npm·node.js
wuhen_n23 分钟前
CSS元素动画篇:基于当前位置的变换动画(三)
前端·css·html·css3·html5
brzhang25 分钟前
告别面条代码!用可视化编程 Flyde 给你的 Node.js/Web 应用逻辑解解耦
前端·后端·架构
brzhang44 分钟前
还在手撸线程?搞懂这 6 大多线程设计模式,并发编程不再难!
前端·后端·架构
拖孩1 小时前
【Nova UI】十四、打造组件库之按钮组件(下):按钮组组件的构建之旅
前端·javascript·vue.js
pixle01 小时前
Vue3 Echarts 3D圆形柱状图实现教程以及封装一个可复用的组件
前端·3d·vue·echarts
Rudon滨海渔村1 小时前
[随笔] 升级uniapp旧项目的vue、pinia、vite、dcloudio依赖包等
前端·vue.js·uni-app
机构师1 小时前
<uniapp><插件><UTS>在uniapp中,创建自己的插件并发布到uni插件市场
javascript·uni-app·vue·插件·hbuilderx·uni
Watermelo6172 小时前
Vue3调度器错误解析,完美解决Unhandled error during execution of scheduler flush.
前端·javascript·vue.js·elementui·html·es6·bug