2

前言

这是一篇关于Chrome扩展插件入门、Vue.js入门的小练习,功能是:在当前浏览的页面点击扩展图标,并点击保存之后,该页面就会存在你的新标签页中。其实就是一个可视书签的内容。
欢迎大家指出代码的不足之处,很多时候都是自己学习自己码代码,太需要别人的意见了。


Demo代码

代码戳这里

Chrome插件预备知识

首先给出一本参考的中文书籍,在练习的过程中有帮到忙。当然,最权威的还是官方文档,只不过像我这种英文不太好星人只能拣自己看得懂的看了。另外还有官方文档的中文版,在英文版看不懂的时候用。

  • manifest.json

    这个文件其实就是你的扩展插件的一个说明书。来人,上代码!

    {
      // 前三个必填
      "manifest_version": 2,
      "name": "bookmark",
      "version": "1.0",
    
      "description": "This extension shows bookmarks",
    
      "browser_action": {
        "default_icon": "icon.png",
        "default_popup": "popup.html"
      },
      
      "chrome_url_overrides": {
            "newtab": "main.html"
        },
      "content_scripts": [
        {
            "matches": ["*://*/*"],
            "js": ["jquery-3.2.1.min.js", "html2canvas.js", "canvas2image.js","contentScripts.js"]
        }
      ],
      "permissions": [
        "tabs"
      ]
    }
       前三个必填的我不想说了,无非就是版本、名称之类的。
    
  • browser_action

这一项是设置你的扩展在浏览器窗口上的小图标,以及点击这个图标弹出的页面的,你会发现文档的写法跟我有些不一样,因为我有点懒,这样写字数比较少,省事儿。同学们不要学我呦。

  • chrome_url_overrides

    顾名思义,重写chrome相关的页面。我这里要重写的是“new tab”,即新标签页,页面的内容入口在main.html。你还可以重写别的页面,比如书签管理页面等,可以参考文档

  • content_scripts

中文翻译过来应该叫内容脚本,它可以运行在你指定的页面之中,可以拿到指定页面的一些信息。指定的页面就是“matches”这一项了。在本练习中,可以看到用正则匹配了所有页面,因为毕竟是要做书签嘛。“js”这一项是一个数组,里面放的就是你在指定页面里用的脚本,前三个都是依赖,最后一个contentScripts.js才是真正搞事情的脚本,注意依赖是有顺序的噢,其实与在<head>标签里引<script>标签是一回事情。

但其实,我总觉得这么个小demo也许用不到内容脚本,但是水平有限,找不到更好的实现方法,期待大牛与我交流。

  • permission

向chrome申请一些权限,这里我申请了tab 浏览器选项卡的权限,因为做书签时我需要当前tab的url。还有一些别的权限,请参考文档


思路整理

通过以上的说明书,应该大致明白这个扩展插件是怎么回事了,接下来该考虑怎么实现功能。

  • 首先,点击扩展图标,弹出一个页面(popup.html),这个页面有个保存按钮,点击这个按钮应当有相应的事件处理函数,此函数的功能就是获取我当前浏览页面的截图以及url等信息,可以写一个js脚本,即popup.js

拿到url的信息比较简单,chrome.tabs这个API下有一些methods,查看文档发现chrome.tab.query可以query到当前的选项卡,成功拿到页面的url和title


但是问题来了,popup.html虽然是在我当前浏览的窗口上弹出来的,但是是与当前页面独立,如何能获取当前页面的截图呢?


如果你在认真看之前的内容的话,现在脑子蹦出来的应该是——content Scripts!
没错,是它 是它 就是它!上文提到了,这个内容脚本可以运行在指定的页面之中,并且貌似可以拿到当前页面的dom结构,所以,可以在contentScripts.js中使用html2canvas插件拿到截图,并且用canvas2html把图片转成base64格式,至于为什么要转成base64,就要想想拿到这个截图之后干什么了

  • 获得当前页面的截图之后,应当把它传递到我们重写的新标签页下(new tab,新选项卡),即main.html(所以转成base64是为了能把图片传到main.html,我发现只有这样传递才能成功),这个页面也应当有个脚本来接收这个图片并且做一些处理,可取名为main.js

然后问题又来了,这几个页面完全独立,要怎么传递东西呢?所以接下去要介绍的是chrome扩展页面间的通信。


Chrome扩展页面间的通信

在查阅这部分的资料时,还蛮头疼的。命令有点多,而且比较长,对于我这样的懒人来说简直是理不清。终于,很多东西不懂不懂,多看几遍也就摸出门道了。

  • 先来理一理,需要收发消息的脚本们。

    popup.js -> contentScripts.js -> main.js


  • 查阅文档发现,发消息有以下几种方式

    chrome.runtime.sendMessage({msg: msg})

    chrome.tab.sendMessage(tab的id, {msg: msg})


  • 接收消息的方法

    chrome.runtime.onMessage.addListener(function(request, sender, sendResponse){})
    发送者发来的对象都在request中,可以用request.msg读取
    你有需要发回的消息时可以用使用sendResponse


接下来就把这几个发送和接收的方法写到各自的脚本中啦。注意发送消息到content Script,必须使用chrome.tabs.sendMessage。

  • popup.js——chrome.tabs.sendMessage
  • contentScripts.js——chrome.runtime.onMessage.addListener和chrome.runtime.sendMessage
  • main.js——chrome.runtime.onMessage.addListener

至此,整个扩展插件的骨架都搭好了。
最前面是不是提到了Vue,好吧其实一开始我是想做个vue的demo来学习学习vue的,只是没想到这个扩展页面上的东西太简单,反而在学习Chrome扩展开发花了更多的时间。Vue.js的相关内容也有,就是太简单了,大家可以去看看源码。


问题

  • 截屏不是对所有页面都有效
  • 只想对页面窗口大小的页面进行截屏,不知道该怎么做
  • 是否可以不使用html2canvas这种插件来实现截屏的效果

问题解决

对于截屏这个问题,终于找到了正确的方法。其实近在眼前,怪我没仔细看文档。

  • chromes.tabs.captureVisibleTab 便可以截取可见页面

虽然使用html2canvas方法繁琐,但也帮助我明白了chrome扩展间的通信方法,因祸得福♪(^∀^●)ノ


Cluster
16 声望1 粉丝