软件测试布道师的江湖

深耕软件测试领域,定期分享技术干货,一起成长!

chrome插件开发详解

1、chrome插件简单介绍

     1.1基本概念

      一个chrome插件其实是压缩在一起的一组文件,包括HTML、CSS、JavaScript脚本,图片文件、还有其它任何需要的文件。插件从本质上来说就是web页面,它们可以使用所有的浏览器提供的API,从XMLHttpRequest到JSON到HTML5全部都有。

      另外,插件可以和web页面交互,或者通过content script 或者cross-original XMLHttpRequests与服务器交互。插件还可以访问浏览器提供的内部功能,例如标签或者书签等。

     1.2开发过程中几个常用的对象

(1)Browser Actions

     browser actions负责插件在浏览器上的展现形式,需要了解的有Icon(图标)、Title、Popup(单击Icon弹出的气泡)。另外还有一个单击图标会触发的事件方法需要了解—chrome.browserAction.onClicked.addListener(function(Tab tab){…})

(2)Desktop Notifications

      Desktop Notifications(桌面通知),通过在右下角弹出一个气泡来提示用户一些重要的事情。 Desktop Notifications 需要了解的有:在配置文件中要声明notifications的权限(这个很重要)、Notifications可以与扩展页面进行交互 :  1.在通知中调用扩展页面的方法:chrome.extension.getBackgroundPage().doThing() 2.从扩展页面调用通知的方法: chrome.extension.getViews({type:”notifiction”}).forEach(function(win)){  wind.doOtherThing });

 Notifications 的创建方式:

 1.简单的文字通知:

   

1  var notification = webkitNotifications.createNotification(‘48.png’ ,  //icon url –can be relative
2  ‘Hello!’,          //notification title
3 
4 ‘Lorem ipsum’    //notification body text;

 

 2.创建一个HTML通知:

       

1 var notification = webkitNotifications.createHTMLNotification( 'notification.html' // html url -              can be relative );

       最后调用notification.show()就显示通知,

(3)Page Actions

   Page Actions 和Browser Actions 相似,只不过Page Actions的图标是出现在地址栏的。可参考browser Actions的用法。

(4)bookmarkets

   chrome.bookmarks 用来创建、组织和管理书签的,这里不做过多介绍。详细参考开发文档。

(5)tabs

   chrome标签页模块用于和浏览器的标签系统交互,它可以创建、修改、重新排列浏览器中的标签。

   这里了解几个比较有用的方法:

  1.captureVisibleTab(integer windowid,object options,function callback)   截取当前网页可见区域

  2.chrome.tabs.create(, object createProperties, function callback)   创建一个标签页

  3.chrome.tabs.executeScript(, integer tabId, object details, function callback)向页面注入javascript脚本执行,这个方法很管用,当你自己创建一个页面的时候。

  4.chrome.tabs.get(, integer tabId, function callback) 获取指定标签页的信息

  5.chrome.tabs.getAllInWindow(, integer windowId, function callback)

  6.chrome.tabs.getCurrent(function callback)  这个也有用,可以获取当前的tab

  7.chrome.tabs.insertCSS(, integer tabId, object details, function callback) 向页面注入css

  8.chrome.tabs.remove(, integer tabId, function callback)  关闭某个标签页

  9.chrome.tabs.onSelectionChanged.addListener(function(integer tabId, object selectInfo) {...});当标签页发生变化时触发这个方法。

(6)window

        使用chrome.windows 模块跟浏览器视窗进行交互,可以使用这么模块在浏览器中创建、修改和重新排列视窗。

  此外还有一些知识点  比如:替代页Override 、选项页、主题、history、Cookies等不是那么主要,可以参考开发文档了解。

  2.插件组成介绍

     首先要了解一个chrome插件的组成:

     如上图所示,一个chrome插件目录大致如此。我下面结合着插件目录对插件组成做一个简单介绍:

     2.1manifest.json主配置文件

首先manifest.json文件,这个文件的名字必须是这个,为了chrome浏览器能够识别解析,

       manifest.json文件的字段如下:

 1 {
 2 
 3         // Required  (版本号在采用写注册表安装的时候必须和写入注册表的版本号一致,否则安装失败)
 4 
 5         "name": "My Extension",   
 6 
 7                "version": "versionString",     
 8 
 9               
10 
11                // Recommended   
12 
13                "description": "A plain text description",   
14 
15                "icons": { ... },  //icons这里需要三种不同分辨率的图片 一般是16*16 48*48 128*128
16 
17                "default_locale": "en",     //支持国际化
18 
19               
20 
21                // Pick one (or none)   
22 
23                "browser_action": {...},  //这个在上面都有介绍到。 
24 
25                "page_action": {...},   
26 
27                "theme": {...},   
28 
29                "app": {...},     
30 
31               
32 
33                // Add any of these that you need   
34 
35                "background_page": "aFile.html",   
36 
37                "chrome_url_overrides": {...},    //替换页  
38 
39                "content_scripts": [...],   
40 
41                "homepage_url": "http://path/to/homepage",   
42 
43                "incognito": "spanning" or "split",   
44 
45                "key": "publicKey",    
46 
47                "minimum_chrome_version": "versionString",   
48 
49                "omnibox": { "keyword" : "aString" },    
50 
51                "options_page": "aFile.html",     //选项的配置页
52 
53                "permissions": [...],    //权限这里很重要,需要使用标签页、window等的要在这里配置权限
54 
55                "plugins": [...],      //和dll交互的时候需要在这里配置  
56 
57                "update_url": "http://path/to/updateInfo.xml" 
58 
59 } 

   首先可以把必须的字段写上,"name”、"version"、“description”、“icons”,后面有需要的可以再添加。

2.2html文件

html文件我们用到的有两种background.html 和popup.html:

      background.html主要是运行在后台,它在插件的生命周期中都存在,比如:你可以将一些持久的数据放到到背景页中,当需要的时候可以从背景页中得到。需要注意的是,使用了background.html,需要在manifest.json文件中要配置“background_page”:background.html。(下面的例子中会有介绍)

      而popup.html是单击chrome浏览器右上角任务栏中或者是地址栏的插件图标时弹出的页面,假如你有单击图标弹出气泡提示的需求,就可以在popup.html上下功夫。同样使用了popup.html就需要在manifest.json文件中要配置:

1 "browser_action": {
2     "default_icon": "images/icon19.png", // optional 
3     "default_title": "Google Mail",      // optional; shown in tooltip 
4     "default_popup": "popup.html"        // optional 
5   },

 下面的例子中会详细的介绍

 2.3js文件 

      Js文件在插件中作用也很大,一般我们会将html中的js代码放到专门的js文件中,而在html中引入。有时当需要去操作页面时也是将写好的js文件注入到对应的标签页面。

使用了js文件,在manifest.json文件中也要配置键值,这个我在开发插件的过程中用到的比较少。详细的可以参考chrome应用开发文档。

2.4images文件

     Image文件夹中存放的是插件的图片资源,由于chrome插件在不同的地方会显示不同分辨率的图标,因此在image文件夹下会存放不同分辨率的图标,一般来说有16*16、48*48、128*128三种分辨率。

     在manifest.json文件中要做如下配置:

1 "icons": {
2 
3          "16": "images/menu_logo.png",
4 
5          "48": "images/extension_logo.png",
6 
7          "128": "images/install_logo.png"
8 
9         }

2.5_locales国际化

     为了国际化您的扩展,您需要把所有用户可见字符串保存在文件名为messages.json的文件里。每当你本地化您的扩展时,您需要在_locales/localeCode下增加这个messages.json文件,localeCode 是一个形如en代表英语的编码。

      下面是一个支持英语(en)、西班牙语(es)和韩语(ko)的国际化扩展文件层次结构图。

      在messages.json文件中定义的结构如下:

 1 {
 2 
 3   "name": {
 4 
 5          "message": "XLFastPass Addin"
 6 
 7   },
 8 
 9     "description": {
10 
11     "message": "一键保存精彩网页,多终端同步,永久珍藏"
12 
13   },
14 
15          "title": {
16 
17     "message": "单击这里将网页保存到快传客户端"
18 
19   }
20 
21 }

     在manifest.json和CSS文件中,像下图一样引用一个字符串:__MSG_messagename__

     在您的扩展JavaScript程序中,像下图一样引用一个字符串: chrome.i18n.getMessage("messagename")

重要提示:如果一个扩展有_locales目录,那么manifest文件必须定义"default_locale"字段内容。

2.6NPAPI插件

     使用HTML和JavaScript开发新扩展是十分容易的事情,不过如果你想在扩展中重用已经开发完成的代码和功能,你可以通过使用NPAPI插件到达目的。NPAPI插件使JavaScript代码能够调用本地二进制代码,比如dll文件。

     使用NPAPI,你需要在扩展的manifest.json文件中加入一个节,描述如何找到你的插件,以及其他一些信息,:

 1 {
 2 
 3   "name": "My extension",
 4 
 5   ...
 6 
 7   "plugins": [
 8 
 9     { "path": "content_plugin.dll", "public": true },
10 
11     { "path": "extension_plugin.dll" }
12 
13   ],
14 
15   ...
16 
17 }

    创建一个HTML文件,mime-type为:application/x-my-extension" ,用于加载你的插件。

 1 <embed type="application/x-my-extension" id="pluginId">
 2 
 3 <script>
 4 
 5   var plugin = document.getElementById("pluginId");
 6 
 7   var result = plugin.myPluginMethod();  // call a method in your plugin
 8 
 9   console.log("my plugin returned: " + result);
10 
11 </script>
12 
13    </embed>

   这样在html中就可以调用dll中定义的方法了。

 

3.插件安装和卸载

3.1.插件安装

chrome插件安装大致可以分为两种:静默安装和拉起浏览器安装。

(1)静默安装

      静默安装也就是通过写注册表安装,个人觉得Google对这种方式支持的不是太好,因此使用这种方式会造成很多问题。

      首先写注册表安装的格式如下:

      在HKEY_LOCAL_MACHINE\SOFTWARE\Google\Chrome\Extensions\下建立一个以插件的id为名字的键值。然后创建两个分别以"path" 和 "version"命名的字符串类型数据项,设置该扩展的位置和版本。如:

1 path: xl_plugin_chrome.crx
2 
3 version: 1.0

采用静默安装遇到的问题及解决方法如下:

  1. 第一次安装时如果有打开的chrome浏览器(或者是默认chrome浏览器在后台运行),会出现安装不上的情况,需要将chrome浏览器重启才能安装插件。
  2. 覆盖安装的时候会出现安装不上的情况,需要在覆盖安装之前将chrome插件已有的配置等清理干净,这样覆盖安装就能成功。
  3. 写入注册表的version一定要和manifest.json文件中配置的一样,不一样会造成安装失败。
  4. 在写注册表安装之后第二次重启chrome浏览器,在右上角会弹出一个“某某插件已安装”的提示,让你确定。这里要用到插件的name,假如是中文的话会出现乱码,这个问题我也没有解决,不过暂时用英文代替吧。

  (2)拉起浏览器安装

      拉起浏览器安装的效果和将crx拖到chrome浏览器的安装效果一样,个人感觉这是Google提倡的安装方式,所以采用这种方式不会出现什么问题。但是这种方式可能用户体验会差一些,因为安装过程中还需要去拉起浏览器。

 (3)版本差异化

     由于chrome浏览器发展很快,所以出现了非常多的版本,他们对插件的影响如下:

     1.chrome浏览器从4.0及以上版本才支持插件,因此3.0及以下版本安装是不成功的;

     2.chrome浏览器从21.0.1180.80m 版本开始要求必须将crx文件拖到“扩展程序”界面才可以安装(如下图所示),因此拉起浏览器安装方式不可行,只能用静默安装的方式。

    

3.2卸载插件

     卸载插件的方式有两种,其实和安装对应,一种是直接在chrome://chrome/extensions/页面切换到开发者模式进行卸载,一种是采用清理安装文件等的方式。

(1)清理插件安装文件、注册表键值

    这种方式需要清理三个地方的内容:

     1. 清理掉注册表中key为插件id的项;

     2.将C:\Documents and Settings\admin\Local Settings\Application Data\Google\Chrome\User Data\Default\Extensions安装目录下的对应插件id名字的安装文件夹清除;

     3.将C:\Documents and Settings\admin\Local Settings\Application Data\Google\Chrome\User Data\Default\ Preferences文件中的对应的插件id名字相关的项清理掉;

      在完成上面的三个清理过程之后还需要注意,在卸载的过程中假如chrome浏览器开着,再打开一个chrome浏览器就会在右上角出现一个白色的框(其实是图标不见了),插件还可以使用。解决方法是重启chrome浏览器。

(2)在chrome://chrome/extensions/页面卸载

     这种卸载方式不会遇到太多的问题,也是Google建议的方式。

 

4.chrome插件打包

      chrome插件都是以crx文件的形式发布的。在chrome://chrome/extensions/页面对插件进行打包

      打包的时候会用到一个pem结尾的密钥文件,这个要保管好,后续版本的插件打包都用这个密钥,这样插件的id就不会发生变化。

      Chrome插件的id也要备份一下,方便后面使用:

      注意:打包时的插件文件要放到硬盘的根目录,然后密钥也要放到同一根目录下,这样才能正确的生成crx文件,否则crx文件会出现不能安装的情况。

5.详细举例(以迅雷快传chrome插件为例)

4.1.manifest.json文件

 1 {
 2 
 3     "default_locale": "zh_CN",
 4 
 5     "name": "__MSG_name__",
 6 
 7     "description": "__MSG_description__",
 8 
 9     "version": "1.0.2",
10 
11     "icons": {
12 
13        "16": "images/menu_logo.png",
14 
15        "48": "images/extension_logo.png",
16 
17        "128": "images/install_logo.png"
18 
19     },
20 
21     /*插件动作配置*/
22 
23     "browser_action": {
24 
25        "default_icon": "images/extension_logo.png",
26 
27        /*图标上的悬浮字*/"default_title": "__MSG_title__"
28 
29     },
30 
31     /*background_page是一个和插件同生命周期的一个脚本,用来它管理一个任务和一些状态*/
32 
33     "background_page": "background.html",
34 
35     "permissions":
36 
37     ["notifications",
38 
39     "background",
40 
41     "<all_urls>",
42 
43     "tabs"],
44 
45     "plugins":
46 
47     [{
48 
49        "path": "npxunlei.dll",
50 
51        "public": true
52 
53     }]
54 
55 }

 

4.2.background.html

 1 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
 2 
 3 <HTML>
 4 
 5  <HEAD>
 6 
 7  <embed id="np_xunlei_plugin" type="application/np_xunlei_plugin" hidden="true">
 8 
 9       <SCRIPT LANGUAGE="JavaScript">
10 
11        
12 
13        /*  var notification = webkitNotifications.createNotification(
14 
15            'images/menu_logo.png',  // icon url - can be relative
16 
17            'Hello!',  // notification title
18 
19            'Lorem ipsum...'  // notification body text
20 
21            );
22 
23            notification.show();
24 
25        */
26 
27            chrome.browserAction.onClicked.addListener(function(tab) {
28 
29              var xl_plugin =document.getElementById('np_xunlei_plugin');
30 
31             
32 
33              var url = tab.url;
34 
35              var urlTitle = tab.title;
36 
37               //alert("url== "+url);
38 
39               //alert("urlTitle=="+urlTitle);
40 
41              /*调用C++程序的方法 url_image 是Base64位的截图data*/
42 
43              chrome.tabs.captureVisibleTab(null, function(img) {
44 
45              /*将Base64 image保存到本地*/
46 
47              xl_plugin.SaveToFastPassPlugin(url,urlTitle,img);
48 
49              });
50 
51            });
52 
53  
54 
55      </SCRIPT>     
56 
57   </embed>
58 
59  </HEAD>
60 
61  <BODY>
62 
63  
64 
65  </BODY>
66 
67 </HTML>

 

4.3. _locales文件

 1 _locales/zh_CN/message.json:
 2 
 3 {
 4 
 5   "name": {
 6 
 7     "message": "XLFastPass Addin"
 8 
 9   },
10 
11     "description": {
12 
13     "message": "一键保存精彩网页,多终端同步,永久珍藏"
14 
15   },
16 
17     "title": {
18 
19     "message": "单击这里将网页保存到快传客户端"
20 
21   }
22 
23 }
24 
25 _locales/zh_TW/message.json:
26 
27 {
28 
29   "name": {
30 
31     "message": "XLFastPass Addin"
32 
33   },
34 
35     "description": {
36 
37     "message": "一键保存精彩网页,多终端同步,永久珍藏"
38 
39   },
40 
41     "title": {
42 
43     "message": "单击这里将网页保存到快传客户端"
44 
45   }
46 
47 }

 

4.4.images文件

在images文件夹下放3个不同分辨率的图标。

4.5.npxunlei.dll

这里的dll是为了拉起快传客户端并将网页的截图保存到本地然后通过快传客户端上传到服务器用的,大家可以根据自己的需要来实现dll文件。

posted @ 2012-09-24 14:42  布道师玄柯  阅读(11478)  评论(8编辑  收藏  举报