5.1 下载

优质
小牛编辑
122浏览
2023-12-01

Chrome提供了downloads API,扩展可以通过此API管理浏览器的下载功能,包括暂停、搜索和取消等。

相对于管理下载,更令人关注的是创建下载的功能。Chrome应用市场中之前包括很多下载页面所有图片等类似功能的扩展,大多数是将图片包含在一个网页中让用户另存为,或者是列出所有URL让用户自行下载。这样做明显不友好,Chrome处于早期版本时,开发者对开放下载功能的呼声也越来越高。所以本节将重点讲解如何让扩展通过downloads接口创建下载,有关进一步管理下载行为的内容请感兴趣的读者自行阅读。完整有关downloads接口的官方文档可以通过http://developer.chrome.com/extensions/downloads阅读。

扩展使用downloads接口需要在Manifest文件中声明downloads权限:

"permissions": [
    "downloads"
]

创建下载可以通过downloads中的download方法实现。download方法包含两个参数,第一个是有关下载的属性对象,包括URL、保存位置、文件名等信息,第二个是创建成功后的回调函数。

chrome.downloads.download(options, callback);

其中options的完整结构如下:

{
    url: 下载文件的url,
    filename: 保存的文件名,
    conflictAction: 重名文件的处理方式,
    saveAs: 是否弹出另存为窗口,
    method: 请求方式(POST或GET),
    headers: 自定义header数组,
    body: POST的数据
}

其中conflictAction的取值只能是uniquify(在文件名后添加带括号的序号保证文件名唯一)、overwrite(覆盖)和prompt(给出提示让用户自行决定重命名或者覆盖)。

filename可以是单纯的文件名,如'foo.txt';也可以带有相对路径,如'mypath/foo.txt'。但不可以是绝对路径,或是一个目录,也不可以在路径中包含上级路径'..'。如这三种情况都是非法的:'/mypath/foo.txt''mypath/''../mypath/foo.txt'

如果给定了filename,同时saveAs属性为true,则弹出的另存为对话框中,文件名一栏的默认值会被设为filename指定的值。

下面让我们来一起编写一个下载当前页面所有图片的扩展。

这个扩展我准备设计成用户在页面点击右键时,菜单中包含一个下载所有图片的选项。这个过程首先要在右键菜单中创建一个选项,我们需要一个background脚本。因为要获取当前页面的图片元素,所以我们要向当前标签页注入脚本。这几点分析清楚之后,我们就可以开始了。

首先创建manifest.json。

{
    "manifest_version": 2,
    "name": "Save all images",
    "version": "1.0",
    "description": "Save all images in current tab",
    "background": {
        "scripts": ["background.js"],
        "persistent": false
    },
    "permissions": [
        "activeTab",
        "contextMenus",
        "downloads"
    ]
}

下面编写background.js文件,这个文件用来创建右键菜单,并在用户点击菜单后向当前标签页注入脚本,最后还要完成下载的行为。

chrome.runtime.onInstalled.addListener(function(){
    chrome.contextMenus.create({
        'id':'saveall',
        'type':'normal',
        'title':'保存所有图片',
    });
});

chrome.contextMenus.onClicked.addListener(function(info, tab){
    if(info.menuItemId == 'saveall'){
        chrome.tabs.executeScript(tab.id, {file: 'main.js'}, function(results){
            if (results && results[0] && results[0].length){
                results[0].forEach(function(url) {
                    chrome.downloads.download({
                        url: url,
                        conflictAction: 'uniquify',
                        saveAs: false
                    });
                });
            }
        });
    }
});

最后来编写注入脚本,main.js。

[].map.call(document.getElementsByTagName('img'), function(img){
    return img.src;
});

至此,通过右键菜单下载所有图片的扩展就编写完成了。

本例中没有指定扩展的图标,但在成熟的产品中,自定义右键菜单时,应当指定一个16像素的图标。

本节所涉及到的代码可以通过https://github.com/sneezry/chrome_extensions_and_apps_programming/tree/master/save_all_images下载得到。