前情提要
jsproxy-chrome-extension
先放上链接: https://github.com/JimmyTinsley/jsproxy-chrome-extension
由于最近经常需要使用到chrome, 加上手头的活忙的差不多了, 终于空出半天可以摸鱼的时间~ 所以打算把之前为jsproxy写的火狐插件移植到chrome上面.
之前开发火狐版本插件的时候是有打算也做一下chrome版本的, 所以大概考察了一下移植难度. 原生的js内容自然是通用的, 所以在逻辑处理上应该是无需修改了. 主要不同的地方在于对浏览器API的调用方式. 对于我在插件中使用到的几个API, 大概有下面这样的对应格式:
// firefox -> chrome
browser.menus.* -> chrome.contextMenus.* //右键菜单
browser.storage.sync.* -> chrome.storage.sync.* //配置储存
browser.tabs.* -> chrome.tabs.* //标签页
browser.pageAction.* -> chrome.pageAction.* //页面功能
值得一提的是, chrome的插件只允许包含pageAction
, browserAction
和app
这三种功能实现方式的一种, 不允许任何形式的共存, 而火狐似乎没有相关的限制. 由于我在火狐上使用的browserAction
仅仅是为了方便打开配置页面而已, 而chrome上可以右键点击插件图标再点击选项快速进入到自定义的配置页面, 所以我就在chrome版本的插件上移除了browserAction
相关的内容.
大体上来说, API调用上的变化就是把browser
关键字替换成chrome
. 实际上火狐使用的这些API都是基于Chromium的API二次开发的, 所以通用性高就不难理解了.
移植过程大部分都很顺利, 就是修改manifest文件, 简单地替换下关键字, 再改改传参方式, 但是还是遇到一个蛮难搞的地方, 没错, 又是回调...
对于需要用到回调内容的API, 火狐和chrome对于回调内容的使用方式有一些区别, 我们可以拿chrome.storage.sync.get/browse.storage.sync.get
这个API举例说明. 这里先引用一下MDN官方对于这两个API区别的描述:
When used within a content script in Firefox versions prior to 52, the Promise returned by
browser.storage.local.get()
is fulfilled with an Array containing one Object. The Object in the Array contains thekeys
found in the storage area, as described above. The Promise is correctly
fulfilled with an Object when used in the background context
(background scripts, popups, options pages, etc.). When this API is used
aschrome.storage.local.get()
, it correctly passes an Object to the callback function.
火狐对于这样的异步函数, 处理回调的办法是返回一个Promise, fulfilled后, 是包含一个对象的数组. 我们可以采用这样的方式, 获取从storage中得到的配置信息:
var item = await browser.storage.sync.get('settings');
var settings = item.settings;
chrome的做法是, 将这个object直接传给回调函数:
chrome.storage.sync.get(['settings'], function(item){
doSomething(item.settings);
});
弄清楚区别之后, 需要在函数结构上作一些修改. 因为像chrome这样使用回调函数的方式, 没有办法将读取出来的数据作为返回值, 再赋值之后给其他函数使用. 像下面这种调用方式是无效的, 永远只会返回undefined
.
var item = chrome.storage.sync.get(['settings']);
// item 永远为 undefined
过程大概就是这样, 移植之后各项功能都可以正常使用~
由于功能上目前没有迫切的新需求, 毕竟我个人使用的话已经非常顺手了...所以短期之内应该不会有新功能的开发, 如果发现bug还是会修一修的.
感谢分享,从中得到启发了,哈哈哈
@Escher 很高兴可以帮助到你😊