chrome插件开发

前言:

  最近有个课程项目,由于对插件开发很感兴趣,所以花了较大的功夫去研究chrome extension开发。最近一阵,读文档、别人的总结、示例代码不在少数,怕以后自己忘了,所以还是趁热打铁写下来。由于本人理解能力有限,对于一些现象给出的解释可能不全面或者有偏差,欢迎大家指正!

  写博客的经历不是很丰富,在此请允许一个小有心得的菜鸟谈谈chrome插件开发的一些知识,希望能对和我一样菜鸟级别起步的人提供便利!

  先来讲讲如何创建属于自己的chrome插件!我假设读者和我一样,会一点点js的语法,能够看得懂jQuery语句。注释中的内容可以无视!

  (实在不会,可以看看 http://www.w3school.com.cn/ 一个绝佳的自学的网站,碰到不懂的时候我也会经常查查这个网站)

 

=========================华丽丽的切割线================================================

 

进入正题:

  首先,我们需要manifest.json文件来声明我要写的插件的相关信息。可以把manifest.json理解成插件的入口,即chrome需要通过manifest.json来理解你的插件要引用哪些文件需要哪些权限插件图标等信息。ok,那就先来写manifest.json文件吧:

  /*以我新手上阵写的插件为例:cyber_watcher,名字看起来挺87的,其实就是追踪用户(也就是浏览器使用者=>我自己)登陆过的网址,并且根据域名进行计数。说白了,就是统计一下自己的上网习惯。*/

复制代码
{
    "manifest_version": 2,
    "name": "cyber watcher",
    "version": "0.0.1",
    "background": { "scripts": ["jquery.min.js", "background.js"] },
    "browser_action": {
        "default_icon": "ico.png",
        "default_title": "cyber watcher", 
        "default_popup": "popup/popup.html"
    },
    "permissions" : ["tabs","http://*/*"],
    "content_scripts":[{
        "matches":["http://*/*"],
        "js":["jquery.min.js", "watcher.js"],
        "run_at":"document_end"
    }]
}
复制代码

“manifest_version”现在都是第二个版本了,现在都需要适应新的规范,所以照着写就可以了(第一个版本我也只是在别人的插件代码中看到过,主要是一些manifest变量命名的方法和语法不同);“name”就是你的插件的名称啦~在需要扩展程序显示名称的时候显示出来的文字;“version”是版本号;“background”定义后台的一些特性,比如可以为后台(后台有什么作用?先留个疑问吧!)添加脚本;“browser_action”设置扩展栏的信息,也就是为你的插件在扩展栏里面添加一个图标(ico.png),鼠标悬浮的时候显示插件名称(cyber watcher),鼠标点击的时候显示一个弹出页面(popup.html);其实还有一个“page_action”,设置的是地址栏的信息,其中地址栏的图标可以控制它是否显现。

/*btw:扩展栏?地址栏?如下图所示-摘自chrome开发手册*/

/*蓝色小格子 就是地址栏的图标,黄色小格子 就是扩展栏(目测也叫工具栏)的图标。如果你的插件只是针对于某些特定的网站,建议设置成page_action,只在登陆特定网站的时候才显示插件图标。btw:为你的插件找个19*19px的图标吧~*/

/*顺便吐槽一下:我就读的学校有个大神写了chrome选课插件,只适用于我校的选课系统,不过他居然把图标设置在扩展栏,想到我居然发现该大神设计不合理的地方,还是有点小开心的呢! */

"permission"设置插件的权限,其中"tabs"允许插件访问标签页,后面的网址允许插件向这些网址发送ajax请求(同时还获取了其他权限,不过对于小插件一般用不到),“http://*/*”星号是通配符,表示的就是所有http请求的页面!“content_scripts”就是你向指定的页面注入的js代码,其中页面由match指定,run_at指定的是这段js载入的时机。

注意:写manifest.json非常痛苦的一件事情就是区分 “[” 和 “{”。在js中,“[”用于定义数组,“{”用于定义对象。基于这种理解,我们再看content_scripts属性的构成:由于一个插件可以针对不止一个网页/网站,content_scripts中就应该定义你所有需要导入js的页面的导入信息,因此是一个数组,最外面是一个“[”。而数组中的每一个元素是一个对象,对象中的每个属性对应了content_scripts的一条导入信息。其中,“js”属性对应需要导入哪些js文件,而导入的js文件不止一个,因此又是一个数组。数组的对象之间用逗号分开,对象的属性之间用逗号分开。不知道这样解释之后,看manifest.json会不会更加清晰呢?

manifest.json写好之后,其中引用过的文件一定要被创建(比如popup.html),否则会报错。

 

========================又来华丽丽的分割线===============================================

 

配置方法:

一个插件需要的基本东西几乎具备了。那插件如何运行呢?

1.打开chrome右上角扩展栏里面,”三条杠“=>"工具"=>"扩展程序",进入到chrome的插件管理页面(这个页面很重要,调试必要,要,要,切克闹);

2.选择“载入正在开发的程序”,然后选定你插件存放的文件目录(即包含了manifest.json的目录),即可;

/*如果你的插件有代码更改,需要点击 重新加载 才能更新插件哦~*/

/*啊咧咧?“打包扩展程序”有什么用?chrome的插件格式是“.crx”后缀的,打包的话就是生成.crx文件,你如果想要把你的插件给别人用的话,可以把.crx文件发给他,然后他直接把.crx拖入到刚才说的插件管理页面,就成功安装了你的插件了!*/

-------------------------------------------------------------

--------------------------------------------------------------------------------------------

-----------------------------------------------------------------------------------------------------------

-----------------------------------------------------------------------------------------------------------

至此,一个插件就配置好了!在写一个实用的插件之前,我们可以先来做点简单的测试项目:

比如我可以在把manifest中的content_scripts写成:

"content_scripts":[{
        "matches":["http://www.baidu.com/*"],
        "js":["test.js"]
    }]

在test.js中写:

复制代码
var div = document.createElement("div");
var body = document.getElementsByTagName("body")[0];
div.innerHTML = "Hello,World!";
div.style.position = "fixed";/*固定定位*/
div.style.left = "100px";
div.style.top = "100px";  /*显示在距离窗口左边100px,顶部100px的位置*/
div.style.color = "red";  /*字体颜色红色*/
div.style.fontSize = "50px";/*字体大小50px*/
body.appendChild(div);
复制代码

/*新手写的代码,没有用jQuery,大神们见笑了*/

然后把manifest写好,按照之前的方法配置一遍,/*记得找个好看的图片作为你的插件图标哦!*/ 如果你已经配置过了,就点击“重新加载”。

登陆 百度,看看是不是在左上角显示了一个大大的“hello,world”呢?

如果你写了popup.html文件,那么你点击右上角自己的插件图标,看看弹出的是不是你写的页面?

/*什么?没有出现预期的效果?两种可能:1.你的代码写错了 2.你一定是在逗我*/

/*代码错了?我怎么知道?

1.打开插件管理页面,看看有没有报错信息,有的话一般都是出现在manifest.json的语法错误上,建议直接copy别人的manifest.json,然后进行修改

2.打开控制台,看看有没有什么报错信息。chrome的话F12就可以快速启动console了。*/

 

====================最后的华丽丽的分割线=================================================

参考阅读:

以上内容,含部分言论,可参见我读过的一篇博客:

[1] http://www.cnblogs.com/guogangj/p/3235703.html 谷歌chrome自然而然找到的博客,写得很好,刚开始起步写插件可以下载他的作品参考(我就是这么做的),我的总结,很大部分是对他的总结的再总结(掺杂了一点点我个人的理解方式)

顺便贴下我写的插件代码(王婆卖瓜,见笑了!TAT):

[2] watcher.zip 追踪自己上网的记录的一个小插件,多一份代码,多一份参考吧...

[3] http://developer.chrome.com/extensions/getstarted chrome插件开发手册上给的样例,全英文的,不过挺好懂的,写的也比较简单,不过绝对是参考范本!


chrome插件(二)-区别三个环境

前言:

  这句话一定要写在前面:这只是一个刚开始学习写插件的人写的总结,我尽可能严谨,但能力限制不允许啊TAT!所以有什么错误,欢迎指正交流~

  注释部分大多为个人理解,未经详细考察推敲,可以直接无视。如有错误,欢迎戳我,及时纠正我的理解误区!thx----q:894355570

  进入正题:在extension的编写过程中,会发现:比如我在background.js里面定义了一个函数,然后在popup页面中不能调用!进一步研究,你会发现后台和popup两者之间,并不能共享变量。事实上,这里有三个环境(上下文),为了描述方便,我喜欢称之为background、popup、content。算上浏览页面自身的脚本,一共有四个环境。他们相互独立,拥有不同的上下文,不能共享任何js变量

/*在同一个上下文中,变量/函数共享同一个命名域/名字空间,所以能够调用同一个文件中其他的变量/函数。比如,我在博客园里有个账号,那么在博客园的域内就能够搜索到我,我也可以通过一定途径,找到同样在博客园的其他人;但你在其他博客网站想查找我的话,无法查到,因为就压根没有我这个用户。*/

===============================华丽丽的分割线===============================================

使用控制台:

  在chrome中,按F12后选择console标签,或者ctrl+shift+J都可以快速启动当前页面的控制台。

  /*我不知道具体的细节,不过就目前的经验看来,当前页面的console和当前页面载入的脚本属于同一个上下文*/

  在console中,你可以访问页面脚本的变量,或者调用页面脚本中的函数。

  关于console的更多巧妙用法,可以参考开发手册:

  http://developer.chrome.com/devtools/docs/console

  以下挑出console中两个非常有用的函数,简直就是在控制台中检测程序的神器:

  1.console.log(msg):在控制台中输出信息。如果参数是对象的话,会输出[Object Object]。/*log其实是把参数当成字符串解析了!*/

  2.console.dir(obj):在控制台中输出信息。不过能够输出对象,通过展开/折叠可以查看对象的各个属性。如下图!/*dir其实是把参数当成对象解析了!不信,可以试试console.dir("abcd");*/

  

  /*一般情况下,我都是在控制台中测试一些基本函数的用法,或者检测自己函数的正确性!把代码直接copy到控制台,然后回车,然后看返回值。*/

 

后台background:

  后台的脚本文件在manifest的“background”属性中设置,比如设置为“background.js”。

  如果你在background里面定义了一个变量,你会发现在ctrl+shift+J跳出来的console里面访问不到该变量!这个时候可以深刻体会到后台和页面脚本处于不同的环境!

  不过,通过在后台控制页面==>点击 generated_background_page.html 就会弹出后台的console啦!在弹出来的console里面,可以与background.js里面的变量/函数进行交互。

-------------------------------------------------------------------------------------------------------------------------------------

  

-------------------------------------------------------------------------------------------------------------------------------------

弹出页面popup:

  所谓弹出页面,就是你点击插件图标时,弹出来的页面。同样,它既不能直接访问后台,也不能访问页面脚本,也处于一个独立的环境之中

  /*机智的你,一定发现了:所谓不能直接访问,言外之意就是可以间接访问。以后再谈*/

  可以直接右键==>审查弹出内容,或者点开弹出页面==>右键==>审查元素 就可以调用popup的专属console啦~

 -----------------------------------------------------------------------------------------

      

--------------------------------------------------------------------------------------------

插件脚本content:

  /*不得不说,content环境好像也只有我自己这么称呼,只是为了方便描述,不是什么规范的称呼。它是插件注入的脚本运行的环境。目测手册上称这个环境为 孤立环境(isolated world)我想表达的意思就是:下文提到的 content环境 = isolated world*/

  特别需要知道的是,content和页面脚本也是互相独立的两个环境,即便content给你的感觉像是和页面脚本距离最近的一个!

  所谓独立,也就是说你不可能在content_scripts的js文件里面,调用原网页脚本的任何变量/函数。

  然而,相当高端的事是:content环境可以访问原页面的DOM结构,也就是说,它和页面脚本一样,能够操作页面的任意一个元素!这就意味着,你可以全面干预最终显示在你眼前的页面!

  之前说过了,你在浏览页面调用出来的控制台,和你的浏览的页面脚本属于同一个环境,也就是说:这个控制台不能访问content_scripts的js文件中的任何变量/函数。说白了,就是content环境没有属于自己的控制台。/*至少根据目前的我的理解来说,没有;不过这样,才能体现 isolated world的高贵冷艳嘛~*/

 

关于Debug:

  在控制台中,有很多手段可以辅助你debug,我自己也是菜鸟,我就贴两个我最常用的手段吧!

  1. 设置断点,在控制台页面选择“Sources”标签,找到你想检查的脚本,然后直接点击行号即可设置断点;

  /*如图,我在watcher.js的第五行设置了断点,但程序运行到这一行时会处于暂停状态,可以通过右上角来继续控制程序的运行。通过右边框中的Call Stack还有Scope variables还可以看到当前环境中的栈情况以及环境变量。*/

  2.console.log()+console.dir()这两个函数配套使用,加到源代码中,可以在控制台中输出临时变量,便于检测逻辑的正确性。

  除此之外,虽然笨,但别忘了还有alert()函数,相当于内置在你源码中的断点:运行到alert函数时,会显示一个警告框,在警告框被处理之前,脚本暂停运行。

============================华丽丽的分割线呦=======================================================

 

小结:

  说到底,写插件的时候,务必要意识到background、popup、content是三个相互独立的环境,算上原页面的脚本环境,一共就有四个独立环境了。其中,content和页面脚本共享页面的DOM结构,能够对文档元素进行修改!我自己画了个图,便于理清我自己的理解,如有错误,欢迎尽早指正(至少我的理解在我目前的编写过程中屡试不爽):

  /*或许你和我一样,很有疑问:为什么要有这么多独立的环境?手册上说:这是为了安全性考虑!毕竟需要意识到:你可以干预别人的网页,反过来,别人也可以通过页面脚本干预你的浏览器,窃取你的浏览数据什么的,都是有可能的!如果不把这些环境隔离开来,我们上网的信息就会暴露在别人面前,想想还是挺可怕的!当然,这只是我个人说服我自己的一种理解,毕竟对网络安全不太懂*/

===================================华丽丽的分割线=============================================

 

参考阅读:

[1]http://developer.chrome.com/extensions/overview 开发手册上给出的一个整体视图的理解

 

=================2014/4/8=补=============================

这里补充一个功能,即chrome.tabs.executeScript函数,它也可以向指定页面植入脚本。

可以看看这里

所不同的是,这个函数只能在background.js里面使用(至少我测试出来是这样,或者我的测试方法有问题),可以传递三个参数,即:

1.目标标签页的id,这个可以通过tabs.query函数来获取特定的标签页;

2.具体插入的脚本,可以直接是代码,{code:“代码”},也可以是文件{file:“code.js”};

3.回调函数。

由于是动态导入的,也就是是说你可以在任何特定情况下导入js代码。

另外,虽然content_scripts是事先准备好的,而executScript是动态导入的,但是,它们属于同一个上下文,也就是说,动态导入的时候,是可以访问到你在content_scripts中定义的变量或者函数的。(这点亲测通过)

=======================================================

和论坛上另外好友交流的时候我又学到了一招,受教于他人才知道的,在这里交流一下:

由于content_scripts和原页面脚本不属于同一个上下文,那问题来了:我偏偏就想调用原页面脚本里面的函数,我就是想访问它的变量或者函数,怎么办?

首先,要基于这样一个前提:我对原页面脚本充分了解,我的目标代码也只针对特定网页

方法:找到原页面脚本所在的<script>标签,然后append要添加的代码

一般来说页面的脚本在<head>标签里面,

1
$( "script" , "head" ).append( "alert('hello,world!')" );

在本地亲测通过,成功调用原页面脚本中定义的函数。由于一般网站构架过于复杂,尚未在知名网站上测试成功过(在百度上测过,跪了,尚不知晓原因)

转自:http://www.cnblogs.com/leenham/p/3597705.html

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值