在线客服

开发谷歌浏览器截图插件

adminadmin 报建百科 2024-04-25 107 10
开发谷歌浏览器截图插件

背景

前端经常会有一些截图/生成快照的需求。但是js并没有支持截图的api,所以网上实现快照的方式原理无外乎都是一个套路来做:

  1. 读取document中的dom节点
  2. 把dom元素画到canvas上
  3. 把canvas转为img

比较成熟的一个插件就是html2canvas,这种方式能实现很多场景的截图需求了,但还是存在几个弊端:

  1. 因为安全策略(浏览器同源策略),无法截取iframe里的内容,此时截取出来可能是黑色/白色(iframe容器大小)
  2. 跨域资源图片也无法截图,原因是出于浏览器安全策略,不允许这未经许可拉取远程网站信息而导致的用户隐私泄露
  3. 因为最终是绘制到canvas上,所以会出现截图不清晰问题

这种方式能够满足大部分的无iframe嵌套场景了,但是对于网页中使用了iframe的页面,就显得无能为力了。这时候很多就该想到怎么借助浏览器本身来帮我们做到截图功能了

浏览器自带的截图功能

其实谷歌浏览器是有自带截图功能的,用法也比较简单:

  1. 进入调试模式 f12/Command +Option +I

  2. 打开命令窗口 ctrl+shift+p/Command+Shift +P

  3. 输入指令capture,会有三个选项

    1. Capture area screenshot 任意区域截图(自选区域)
    2. Capture full size screenshot 截取全屏
    3. Capture node screenshot node模式
    4. Capture screenshot 截取当前范围

    用鼠标点击或者键盘选择就可以使用对应的功能了

但是这个操作成本有点大,对于外行人来说,需要经过一定的培训才会使用,这样的话就会增加培训成本,第二个的话,这个截图无法耦合到项目中,会增加操作成本,最终效果可能还不如使用譬如微信qq提供的快捷截图功能,强行安利这个的话显得很麻瓜

开发截图插件,与项目耦合

虽然谷歌商店中也有其他好用的截图插件,但是实际效果可能跟使用自带的截图功能差不多,还是无法跟项目产生联动效果。所以需要提供一个操作成本更低的功能给用户使用,这时候就可以想到,为什么我们项目中不能调用自带的截图功能呢?想法很美好,现实很残酷,因为谷歌js引擎的运行环境和谷歌插件的运行环境互相隔离的,所以我们无法通过js去调用到对应的api,所以需要自己开发一个插件来实现这样的功能。自己开发有几个优缺点:

  1. 需要额外的安装插件,用户的学习成本和技术支持的额外支出(比较明显的一个缺点)
  2. 技术的学习成本
  3. 可拓展性强,可以在此基础上拓展其他功能,是一条可持续发展道路
  4. 可维护性强,因为插件是一个独立的项目

权衡下来,可以自己动手做一下。

需要了解的基本信息

谷歌浏览器插件开发文档(不然经常打不开)

因为是外网,所以可能出现无法访问的情况,无法访问的同学也可以使用360浏览器的插件开发指南地址来,因为用的内核是一样的,所以大部分api还是一致的

创建manifest.json,这是插件的元数据,插件的配置信息,任何插件都必须要有这个文件,任何插件都必须要有这个文件

{
  "manifest_version": 2,
  "name": "插件名",
  "version": "1.0", // 用来判断是否需要更新
  "description": "插件描述",
  "browser_action": {
      "default_icon": "static/favicon.ico", // 插件图标
      "default_title": "插件图标上显示的内容",
      "default_popup": "pages/popup.html"
  },
  "background": { // 后台运行的js,相当于后台进程
      "scripts": ["scripts/background.js"],
      "persistent": false
  },
  "permissions": [ // 授权信息 - 那些网站或者其他tab的授权
    "tabs",
    "unlimitedStorage",
    "notifications",
    "history",
    "activeTab",
    "storage",
    "webRequestBlocking",
    "*://*/*",
    "http://*/*",
    "https://*/*"
  ],
  "web_accessible_resources": [ // 注入到网页的内容
      "scripts/inject.js"
  ],
  "content_scripts": [{ // 内容js
      "matches": ["http://*/*","https://*/*", "*://*/*"], // 匹配那些网站
      "js": ["scripts/jquery.min.js", "scripts/inject.js"],
      "run_at": "document_start"
  }]
}

项目结构

    ├── scripts                         脚本内容
    │   ├── background.js
    │   ├── index.js
    │   ├── inject.js
    │   ├── jquery.min.js
    │   ├── popup.js
    ├── pages                           页面内容(弹出页,背景页)
    ├── static                          静态资源文件
    ├── styles                          样式
    ├── manifest.json                   chrome插件配置
    ├── README.md                       项目描述文件

代码示例

popup.html 点击图标显示的内容, 在browser_action.default_popup 设置

<body>
  <ul>
    <li class="CaptureScreen">网页截图</li>
  </ul>
</body>
<script src="../scripts/index.js"></script>

scripts/index.js 入口页

const $CaptureScreenBtn = $('.CaptureScreen') // 截屏按钮
const popup = {
  // 初始化
  _init () {
    this._initialEvent()
    this._initScript()
  },
  // 事件初始化
  _initialEvent () {
    $CaptureScreenBtn.click(this.handleCaptureScreen)
  },
  // 脚本初始化
  _initScript () {
    this._sendMsg({ action: 'INJECT_SCRIPT' })
  },
  // 发送消息,和html通讯
  _sendMsg (message, callback) {
    // 对runtime发送消息
    chrome.runtime.sendMessage(JSON.stringify(message), function(response) {
      if (callback) callback(response)
    })
  },
  // 接收消息
  _getMsg () {
    // 监听runtime中的信息
    chrome.runtime.onMessage.addListener(function (request, sender, sendResponse) {
      switch (request.action) {
        default:
          break
      }
    })
  },
  // 开始截屏
  handleCaptureScreen () {
    // 获取当前窗口 -> 回调函数包括当前窗口的详细信息,如窗口id等
    chrome.windows.getCurrent(function (win) {
      // 抓取当前tab的内容
      chrome.tabs.captureVisibleTab(win.id, {}, function (dataUrl) {
        const info = {
          action: 'CAPTURE_SCREEN',
          payload: dataUrl
        }
        popup._sendMsg(info)
      })
    })
  }
}

scripts/background.js

  • 后台进程,用于监听消息和转发消息
  • 可以操作html
// 消息群集
chrome.runtime.onMessage.addListener(onRuntimeMessage)

function sendPostMsg (info) {
  window.postMessage(JSON.stringify(info), '*')
}

// 监听runtime消息
/**
 * @param {*} request
 * @param {*} sender
 * @param {*} sendResponse
 */
function onRuntimeMessage (request, _, sendResponse) {
  // Tips: 需要sendResponse,不然可能会阻塞其他消息
  const { action, payload } = JSON.parse(request)
  sendResponse()
}

// 向网页注入js代码
function injectScript () {
  const link = 'scripts/inject.js'
  const temp = document.createElement('script')
  temp.setAttribute('type', 'text/javascript')
  // 获得的地址类似:chrome-extension://ihcokhadfjfchaeagdoclpnjdiokfakg/js/inject.js
  temp.src = chrome.extension.getURL(link)
  temp.onload = function() {
    // 放在页面不好看,执行完后移除掉
    this.parentNode.removeChild(this)
  }
  document.head.appendChild(temp)
}

scripts/inject.js 此代码会注入到网页,所以在这边做为插件和网页的桥梁,通过postmessage来交互

// 监听消息
window.addEventListener('message', receivedMessage, false)

// 发送postmessage消息
function sendPostMsg (info) {
  window.postMessage(JSON.stringify(info), '*')
}

调试

不管是撸代码的时候还是写完逻辑的时候,我们都期望能根据实际的表现来做出对应的操作,所以就涉及到调试了。Chrome直接支持javascript的调试,拥有了Chrome,就相当于拥有了一个强大的javascript调试器了。

调试Content Script

打开开发者工具,点击sources,找到对应的文件-> scripts/index.js,点击打开,就可以和平时调试js一样调试了

调试Background

由于background和content script并不在同一个运行环境中,因此上面的方法是看不到Background的javascript的。要调试Background,还需要打开插件页,也就是“chrome://extensions”。点对应的插件的“generated background page.html”,就出现了调试窗口,接下来的操作就跟前面的类似了。

调试Popup

虽然Popup和Background是处于同一运行环境中,但在刚才的Background的调试窗口中是看不到Popup的代码的。所以需要审核弹出内容,然后就跟之前的调试操作差不多了

调试inject

inject的话就会把代码注入到网页中,和conten相似的方式即可

总结

因为之前没有相关的开发经验,所以开始的时候会有点慌张,其实发现只要放平心态,认真仔细的阅读开发文档,入门还是不难的。通过这次的实践,我差不多已经知道怎么去开发一款chrome插件了,当然,chrom插件的功能是非常强大的,这次用到的仅是冰山一角,要深入,还需要更加充分阅读文档和实践了。

本网站是一个以CSS、JavaScript、Vue、HTML为核心的前端开发技术网站。我们致力于为广大前端开发者提供专业、全面、实用的前端开发知识和技术支持。 在本网站中,您可以学习到最新的前端开发技术,了解前端开发的最新趋势和最佳实践。我们提供丰富的教程和案例,让您可以快速掌握前端开发的核心技术和流程。 本网站还提供一系列实用的工具和插件,帮助您更加高效地进行前端开发工作。我们提供的工具和插件都经过精心设计和优化,可以帮助您节省时间和精力,提升开发效率。 除此之外,本网站还拥有一个活跃的社区,您可以在社区中与其他前端开发者交流技术、分享经验、解决问题。我们相信,社区的力量可以帮助您更好地成长和进步。 在本网站中,您可以找到您需要的一切前端开发资源,让您成为一名更加优秀的前端开发者。欢迎您加入我们的大家庭,一起探索前端开发的无限可能!
代办报建

本公司承接江浙沪报建代办施工许可证。
联系人:张经理,18321657689(微信同号)。

喜欢0发布评论

10条评论

  • 游客 发表于 2个月前

    视死如归的架势啊!https://sdceda.com/shi/106192256/

  • 游客 发表于 2个月前

    这么经典的话只有楼主能想到!http://nhuu.yntvexp.net/test/226859314.html

  • 游客 发表于 2个月前

    楼主很有经验啊!http://www.dnf70.com/2571.html

  • 游客 发表于 1周前

    大神就是大神,这么经典!http://www.guangcexing.net/voddetail/MKfHJSNj.html

  • 游客 发表于 1周前

    视死如归的架势啊!http://www.guangcexing.net/voddetail/ekBGPbDE.html

发表评论

  • 昵称(必填)
  • 邮箱
  • 网址