目录:

如果你对GmailAssist感兴趣,可以在chrome商店中搜索“Gmail助手”,或点击这里直接访问商店来安装试用;
如果你对GmailAssist的源码感兴趣,可以在我的GitHub上查看它的源码。


一、数据本地存储常用的两种方式

1. HTML5 的 localStorage

在第二篇中说过,chrome扩展中的脚本都可以调用H5的一切API,自然localStorage也不例外。而localStorage的两种形式:sessionStorage 和 localStorage 分别可以看成临时和永久存储:后者永久留在硬盘上,除非你在程序里remove掉,或者手动去删掉;而前者,对在chrome中而言,本地存的数据的生存时间就等于相应标签的生存时间。(这基本上是二者的唯一区别)

localStorage 有 setItem, getItem, removeItem, key, clear 这5个方法。localStorage中都是以 key/value的形式来存储数据的,存储的数据类型都是字符串。并且是明文,没有加密(所以用户密码啥的可不能存啊)。

GmailAssist开发初期,OAuth2的认证一开始搞得我一头雾水,好不容易大概懂了原理,又觉得自己很难很好地拿js实现一个认证的模块。Chrome给扩展程序的API中虽然有OAuth2相关的接口,但感觉好像不是很好用(现在回过头来看,只是自己当时理解有问题,另外当时偷懒了没去好好找好好学google给的例子程序)。于是从网上找来了一个现成的轮子(就是这个),源码和使用说明都很详细,就直接拿来用了。现在有了对js语法的进一步理解,回头看看已经能清晰理解这份源码了。其中保存授权token等信息都是直接使用的 localStorage,查了查发现还是很简单好用的。可以简单理解为大号的cookie。(cookie允许4K,localStorage允许5M)。

可以通过 localStorage 的API们访问数据,也可以直接像访问js变量一样访问。下面是从网上摘抄的例子:

//可以像对象字面量那样使用Web Storage:
localStorage.fresh = “vfresh.org”; //设置一个键值
var a = localStorage.fresh; //获取键值
delete localStorage['fresh']; //删除键值
//或者使用它的API:
localStorage.setItem(“fresh”,“vfresh.org”); //设置一个键值
localStorage.getItem(“fresh”); //获取一个键值
localStorage.key(0); //获取指定下标的键的名称(如同Array)
localStorage.removeItem(“fresh”); //删除一个键值
localStorage.clear(); //清空storage

注意一点!虽然所以脚本都可以访问 localStorage 接口,但访问时仍然是基于当前的域的。也就是说 content script 们和 background script 是无法通过 localStorage 访问到同一块本地数据的!(前者域是当前浏览页面站点,后者是扩展程序自己的域“chrome://extension-id/”,如下图是localStorage 所存放的本地文件夹,从命名就可以看出这些文件对应的域不同)

最后说一下,localStorage 既然是永久保存在本地的,那它在硬盘的什么位置呢?如果我想直接看里面存的值,该怎么看呢?

硬盘位置:C:\Users\your_Username\AppData\Local\Google\Chrome\User Data\Default\Local Storage 。里面一个个的文件可以用SQLite打开查看。更方便的一个途径是直接在Chrome中查看和修改:

打开chrome –> 访问chrome://extensions/ (或从浏览器的设置中,找到“扩展程序”)-> 点击你要看的扩展程序相关信息里的“背景页”-> 在 resource 中的localStorage 处即可查看,双击即可修改。(如下图)

2. Chrome.storage

GmailAssist中未涉及,就不举例细说了,详细内容可以看官方文档。只谈它和 localStorage 有什么异同:

同:

  • 可以认为 chrome.storage 本身就是对 localStorage 的一个封装。所以显然,后者的功能它都有。
  • 它存的也是明文。

异:(我直接摘抄了汉化的文档

这一 API 为扩展程序的存储需要而特别优化,它提供了与 localStorage API 相同的能力,但是具有如下几个重要的区别:

  • 用户数据可以通过 Chrome 浏览器的同步功能自动同步(使用 storage.sync)。
  • 您的扩展程序的内容脚本可以直接访问用户数据,而不需要后台页面。
  • 即使使用分离式隐身行为,用户的扩展程序设置也会保留。
  • 它是异步的,并且能够进行大量的读写操作,因此比阻塞和串行化的 localStorage API 更快。
  • 用户数据可以存储为对象(localStorage API 以字符串方式存储数据)。
  • 可以读取管理员为扩展程序配置的企业策略(使用 storage.managed 和架构)。

3. 何时用哪个

分别说下这两种方式的优势劣势,选择就很显然了。

localStorage:

优势:可以像普通的js变量一样使用,简单方便。

劣势:

  1. content script 无法和 background 共同访问一个域的数据,只能通过第二篇中提过的 sendMessage 来交流数据;
  2. 不像chrome.storage 是用异步方式访问数据,localStorage相对在访问数据略多时会比 chrome.storage 慢;
  3. 隐身模式下无法访问数据;
  4. 如果扩展程序的一些设置参数是用 localStorage 保存在本地的,用户在其他计算机上无法获得这份设置的同步备份,而chrome.storage通过 sync的设置就可以实现这种同步;
  5. 存储数据都是字符串,若需要对象,还需要手动转一下(虽然也不麻烦吧…)。

chrome.storage:

优势:(就和上面的劣势相对嘛)

  1. content script可以使用.storage 接口来访问扩展程序的域的数据;
  2. 异步访问,快;
  3. 隐身模式下仍可以访问数据;
  4. 联网并登陆chrome时,将自动同步 sync 域的数据;
  5. 可以直接存对象类型的数据。

劣势:异步访问导致需要回调函数来处理获取的数据,不能像localStorage那样直接像js变量一样访问。

4. 还有一种方式 Web SQL

这种我没用过,不多提了。查过一些与它相关的东西,我的感觉是它至少对于开发 GmailAssist 这种本地存东西不多,而且没有什么需要在本地执行复杂查询的扩展程序而言,不合适。

二、下载

chrome 扩展程序要发起文件下载,必须通过chrome.downloads API 来完成。没什么不好理解的地方,要用的话就好好看看文档就都明白了。我尝试写写也感觉写不出啥,无非是拷贝。所以直接给出这个我认为已经写得很清楚的电子书章节的链接吧。

结合GmailAssist 说一下,我的下载功能的实现。

需求是:希望用户可以在附件列表中勾选想要下载的项目,进行批量下载。

实现是:通过一个表,每行给个复选框,然后把每个复选框对应的附件的下载地址(这个地址是通过gmail API获取邮件信息中的partid来生成的,更具体的我会在说gmail API时提到)作为参数,来调用 chrome.downloads.download 方法。但 partid 是在content script中获取的,下载地址自然地就在content script中拼出来了,然而 content script能调用的chrome.* API中很不幸地没有包括 .downloads 。咋整?谁能调这个API就把下载的逻辑写在谁那,然后通过 sendMessage 把 url 传给它呗。

于是我的 background.js 中就有如下代码:

chrome.runtime.onMessage.addListener(function (message, sender, sendResponse) {
if (message.url) {
chrome.downloads.download({
url: message.url,
conflictAction: 'uniquify',
saveAs: false
});
} else if (...) {
...//其他的必须在后台处理的逻辑
}
});

当然前提是必须在 manifest.json 中声明使用 download 接口的权限:

{
...
"permissions": [
"downloads"
],
...
}

然后在 content.js 中:

btnDownload.onclick = function () {
var id2 = 0;//id2用于遍历附件列表,找出谁被用户选中了,需要下载
for (id2 = 0; id2 < visibleRows.length; id2++) {
var chebox = document.getElementById("checkbox_" + id2);
if (chebox.checked == true) {
var url = 'https://mail.google.com/mail/u/0/?ui=2&ik=undefined&view=att&th=' + visibleRows[id2].split('|-|')[6] + '&attid=0.' + vis                ibleRows[id2].split('|-|')[7] + '&disp=safe&zw';//这句就是在拼下载地址
chrome.runtime.sendMessage({url: url}, function (response) {
        ...//这里可以针对返回的 response 做些操作,不过我这里不需要
});
}
}
};

这样就完成了下载。

Chrome扩展开发之三——Chrome扩展中的数据本地存储和下载的更多相关文章

  1. Chrome扩展开发之一——Chrome扩展的文件结构

    目录: 0.Chrome扩展开发(Gmail附件管理助手)系列之〇——概述 1.Chrome扩展开发之一——Chrome扩展的文件结构 2.Chrome扩展开发之二——Chrome扩展中脚本的运行机制 ...

  2. 常见浏览器扩展开发笔记(chrome firefox 360 baidu qq sougou liebao uc opera)

    浏览器扩展开发貌似时下很冷门啊,但是不少企业还是有类似的应用,360的抢票插件啊,笔者最近在做的网页翻译扩展之类的.笔者在开发的过程中,遇到了不少坑,说是坑,说白了就是各个厂商支持的API不统一导致的 ...

  3. PHP扩展开发-简单类扩展

    今天来学习简单类扩展开发 实现目标为如下php的类 <?php class classext(){ private $username; CONST URL="http://www.g ...

  4. PHP扩展开发:第一个扩展

    在上一篇文章<PHP扩展开发:安装PHP>我们已经将开发PHP扩展的PHP环境安装成功,那么接下来采用最简单直接的方式创建第一个扩展. 我们先假设业务场景,是需要有这么一个扩展,提供一个叫 ...

  5. firefox扩展开发(一) : 扩展的基本结构

    用过firefox的人肯定要安装firefox的扩展,这样才能发挥火狐的全部实力.一般扩展是一个后缀为.xpi的文件,其实这个文件就是zip格式的压缩包,压缩了一个扩展所需要的所有目录和文件,基本的目 ...

  6. HTML 5 中WebStorage实现数据本地存储

    webstorage 分sessionStorage和localstorage,sessionStorage是暂时保存,localStorage是永久保存. sessionStorage假设浏览器关闭 ...

  7. Chrome扩展开发之二——Chrome扩展中脚本的运行机制和通信方式

    目录: 0.Chrome扩展开发(Gmail附件管理助手)系列之〇——概述 1.Chrome扩展开发之一——Chrome扩展的文件结构 2.Chrome扩展开发之二——Chrome扩展中脚本的运行机制 ...

  8. Chrome扩展开发(Gmail附件管理助手)系列之〇——概述

    目录: 0.Chrome扩展开发(Gmail附件管理助手)系列之〇——概述 1.Chrome扩展开发之一——Chrome扩展的文件结构 2.Chrome扩展开发之二——Chrome扩展中脚本的运行机制 ...

  9. Chrome扩展开发之四——核心功能的实现思路

    目录: 0.Chrome扩展开发(Gmail附件管理助手)系列之〇——概述 1.Chrome扩展开发之一——Chrome扩展的文件结构 2.Chrome扩展开发之二——Chrome扩展中脚本的运行机制 ...

随机推荐

  1. Effective Java 55 Optimize judiciously

    Principle Strive to write good programs rather than fast ones. Strive to avoid design decisions that ...

  2. JavaScript Patterns 2.12 Writing API Docs

    Free and open source tools for doc generation: the JSDoc Toolkit (http://code.google.com/p/jsdoc-too ...

  3. Windows Server 2008 下ASP程序连接ORACLE数据库驱动错误

    今天开发那边升级.改造系统过程中,在测试服务器碰到关于ASP程序连接ORACLE数据库的小问题,虽然是小问题,但是整起来真要命啊,花了不少时间,主要是ASP程序啊,这种上古神器,哥还是当年毕业的时候弄 ...

  4. 在Ubuntu Server下搭建LAMP环境学习记录

    更新于2015/6/16日,因图片地址失效,请在此地址查看:http://note.youdao.com/share/?id=1c249ae6dc6150cbf692adec67b23a33& ...

  5. NOIP2008 T3 传纸条 解题报告——S.B.S.

    题目描述 小渊和小轩是好朋友也是同班同学,他们在一起总有谈不完的话题.一次素质拓展活动中,班上同学安排做成一个m行n列的矩阵,而小渊和小轩被安排在矩阵对角线的两端,因此,他们就无法直接交谈了.幸运的是 ...

  6. uva 1152 4 values whose sum is zero ——yhx

    The SUM problem can be formulated as follows: given four lists A;B;C;D of integer values, computehow ...

  7. [ubuntu]中文用户目录路径改英文

    ubuntu中文版home文件夹里用目录的"桌面"."图片"."视频"虽然对于中文使用者看起来舒适直观,但是对于bash使用来说简直是障碍. ...

  8. ZOJ 3232 It's not Floyd Algorithm --强连通分量+Floyd

    题意:给你一个传递闭包的矩阵,mp[u][v] = 1表示u可以到达v,为0代表不可到达,问你至少需要多少条边组成的传递闭包符合这个矩阵给出的关系 分析:考虑一个强连通分量,如果这个分量有n个节点,那 ...

  9. HDU 1698 & UESTC 1228 Just a hook

    算是线段树中的一道水题了,必须用到懒操作,否则会超时.或者也可以刚开始不计算和,只更新节点,最后算整个线段的颜色和. 1.懒操作法 /* 908ms 3448KB in HDU OJ*/ #inclu ...

  10. MySQL数据库学习笔记(五)----MySQL字符串函数、日期时间函数

    一.常见字符串函数: 1.CHAR_LENGTH  获取长度(字符为单位) 2.FORMAT  格式化 3.INSERT  替换的方式插入 4.INSTR  获取位置 5.LEFT/RIGHT  取左 ...