阅读 281

web页面截图插件

背景

功能要求:在项目的当前页面截图并对页面进行一些标注等操作,在按下确定按钮后将图片保存数据库

html2canvas

  • 通过html2canvas进行截图然后编辑保存----kscreenshot
  • kscreenshot使用html2canvas 升级版本到1.0.0-rc.7

缺点:

  1. 作者不建议在生产环境使用
  2. 对css3的动画样式不兼容(对动画进行替换如transition: left 2s;不适用all)
  1. 对iframe标签不支持出现空白(可以采用ngxin进行代理或是在截图前将iframe标签进行使用html2canavs先转化---但还是有出现iframe标签里的一些图片截不到空白情况)
  2. 对svg图标,视频等不兼容
  1. kscreenshot在线上不可以直接使用源码(会出现报错找不到此对象),修改源码后需要再次build后才可以使用build后的包或是再次发布npm通过下载引用

rasterizeHTML

缺点:

  1. 不支持canvas,video等
  2. 项目中使用比较多的canvas

\

google插件截图

思路

从当前页面点击后通过页面通知google插件进行截图,google插件的content脚本(此脚本不能直接条用一些google的方法如tabs对象下的)收到页面的消息后再通知google插件的background或是popup调用google的方法chrome.tabs.captureVisibleTab()进行截图,截完图后将图片返回和通知content脚本,由content脚本通知页面已经截完图,通过触发自定义事件,页面自定义的事件中监听收到后将图片放回kscreenshot进行截图

目录

├── background.js    //事件页面(backgrund)
├── myscript.js      //内容脚本(content)
├── popup.html       //用户界面网页(popup不是必须的)
├── manifest.json		 //扩展程序的各种信息必须的,且是核心
├── static    			 // 扩展的图标
│   ├── 48.png
复制代码

manifest.json --核心文件

{
    "name": "SmallScreenshot",// 插件名称
    "description": "Quickly take screenshot of current tab", 
    "version": "0.1.5",
    "manifest_version": 2,// 固定
    "background": {//后台页面/事件页面(backgrund)
      "persistent": false,
    "scripts": ["background.js"] 
    },
    "content_scripts": [//内容脚本(content)
      {
        "js": ["myscript.js"],
        "matches": ["http://*/*", "https://*/*","<all_urls>"]
      }
    ],
    "browser_action": { //用户界面网页(popup)
      "default_icon": "static/128.png",
      "default_title": "my Take Screenshot",
       "default_popup": "popup.html"   // 不允许内联JavaScript。
    },
    "icons": {
      "48": "static/48.png",
      "128": "static/128.png"
    },
    "permissions": ["downloads","alarms","<all_urls>"]
  }
  
复制代码

项目开发

Chrome插件可以分为三部分,分别运行在不同的环境。

后台页面/事件页面(background)

  1. 定义:顾名思义,后台网页是运行在浏览器后台的,随着浏览器的启动开始运行,浏览器关闭结束运行。 事件页面则是需要调用时加载,脚本空闲时被卸载,两者都是运行在后台。
  2. 调试backgrund:在扩展管理页面,在安装的扩展上有背景页按钮点击会弹出background页面的DevTools。
"background": {//后台页面/事件页面(backgrund)
      "persistent": false,
    "scripts": ["background.js"] 
    },
复制代码

工具栏popup界面(popup)

  1. 定义:点击工具栏/地址栏(具体位置取决于配置文件)插件图标出来的弹窗其实就是一个html页面,弹窗要显示的文件,和工具栏小图标在manifest.json文件中配置。

调试popup:在工具栏的扩展小图标上右击选择审查弹出内容 会弹出Chrome的DevTools,调试方式和普通页面一样。

"browser_action": { //用户界面网页(popup)
      "default_icon": "static/128.png",
      "default_title": "my Take Screenshot",
       "default_popup": "popup.html"   // 不允许内联JavaScript。
    },
复制代码

内容脚本(content)

  1. 定义:安装插件后每打开一个网页可以将content脚本注入到页面中,内容脚本可以读取浏览器访问的网页的细节,并且可以修改页面。
  2. 调试content:content脚本是直接注入到页面中的所有直接在页面打开Devtools就能调试了。
 "content_scripts": [//内容脚本(content)
      {
        "js": ["myscript.js"],
        "matches": ["http://*/*", "https://*/*","<all_urls>"]
      }
    ],
复制代码

web页面与content,popup,background之间的通信

\

安装扩展

首先需要打开Chrome扩展管理页面打开开发者模式,普通模式下Chrome是禁止安装非商店下载的扩展的。

打开开发者模式后直接将crx/zip文件拖入浏览器即可安装。

也可以通过导航栏的加载已解压扩展程序来安装(需要解压zip文件)

1.如果使用zip包,打包要在manifest.json 的同一级别中压缩所有文件。

yourappfolder
   |_manifest.json
   |_popup.html
复制代码

遇到的问题

  1. 报错:Unchecked runtime.lastError: The message port closed before a response was received.

Unchecked runtime.lastError:消息端口在收到响应之前关闭。

造成报错原因:chrome.runtime.sendMessage给background.js或是其他页面发送消息是,接收消息方即是chrome.runtime.onMessage.addListener的回调函数没有对发送消息这回复确认信息sendResponse()

解决方案通过接收方的chrome.runtime.onMessage.addListener的回调函数回复信息

 // 发送方
  chrome.runtime.sendMessage(null,JSON.stringify({ greeting: '你好,我是content-script呀,我主动发消息给后台!' }), function (response) {
    // 收到浏览器后台的消息
    console.log('截图完成', response);
  });
 //接收方
 chrome.runtime.onMessage.addListener(function (message, sender, sendResponse) {
  	// 回复信息
     sendResponse({ status: true });
  });
复制代码
  1. 截图到的图片不是当前窗口的或是截不到图

如果从popup或者background发送消息到content中需要先确认当前的content,使用chrome.tabs.query可以找到当前激活的窗口

/** * 获取具有指定属性的所有标签页,如果没有指定任何属性的话则获取所有标签页。
 * @params {object} queryInfo
 * @params {function} callback ( tab: []) => {}
 */
chrome.tabs.query(object queryInfo, function callback)

queryInfo = {
    active: boolean, // 标签页在窗口中是否为活动标签页。
    pinned: boolean, // 标签页是否固定。
    highlighted: boolean, // 标签页是否高亮突出。
    currentWindow: boolean, // 标签页是否在当前窗口中。
    lastFocusedWindow: boolean, // 标签页是否在前一个具有焦点的窗口中。
    status: enum['loading','complete'], // 标签页是否已经加载完成。
    title: string, // 匹配页面标题的表达式。
    url: string, // 匹配标签页的 URL 表达式。注意:片段标识符不会匹配
    windowId: integer, // 父窗口标识符,或者为 windows.WINDOW_ID_CURRENT,表示当前窗口。
    windowType: enum['normal','popup','panel','app'],  // 标签页所在窗口的类型。
    index: integer, // 标签页在窗口中的位置
}
    // 通过window的id查找截图
    chrome.tabs.query({}, function (tabs) {
      if (!tabs.length || !t_sender) return;
      //t_sender代码接收到请求的窗口信息
      const curTab = tabs.find((item) => item.windowId === t_sender.tab.windowId);
      chrome.tabs.captureVisibleTab(curTab.windowId, { format: 'png', quality: 100 }, function (image) {
        chrome.tabs.sendMessage(t_sender.tab.id, { canvas: image }, function (response) {
          console.log(response);
        });
      });
    });
复制代码
文章分类
前端
文章标签