FunTester Chrome Extension 历史记录、下载记录和存储管理

FunTester · 2025年01月09日 · 741 次阅读

在现代浏览器扩展开发中,如何高效地管理历史记录、优化下载体验,以及构建灵活的数据存储方案,已经成为开发者们关注的焦点。今天,我们将深入探讨 Chrome 提供的 历史浏览记录 API、下载管理 API 和 存储管理 API,并通过一个实用项目带你快速上手这些功能,让你的插件不仅智能,还贴心。

历史浏览记录

基础功能

  1. 数据查询:使用 chrome.history.search 方法,根据关键词和时间范围搜索用户的浏览历史记录。
chrome.history.search({ text: '', startTime: Date.now() - 7 * 24 * 60 * 60 * 1000 }, (results) => {
    console.log(results); // 输出最近 7 天的历史记录
});
  1. 访问详情:借助 chrome.history.getVisits 方法,获取特定页面的访问时间和来源信息。
chrome.history.getVisits({ url: 'https://example.com' }, (details) => {
    console.log(details); // 输出访问时间和跳转来源
});
  1. 隐私保护

- 删除单个 URL 的历史记录:

chrome.history.deleteUrl({ url: 'https://example.com' }, () => {
    console.log('URL 已删除');
});

- 清空所有历史记录:

chrome.history.deleteAll(() => {
    console.log('所有历史记录已清空');
});

进阶内容

完整 API 函数列表:

  • chrome.history.search:用于按条件检索历史记录。
    参数:
    • text:匹配的关键词。
    • startTimeendTime:搜索时间范围。
    • maxResults:返回结果的最大数量。
  • chrome.history.getVisits
    获取指定 URL 的访问记录详情,包括访问时间、来源等。
  • chrome.history.deleteUrl:删除指定 URL 的历史记录。
  • chrome.history.deleteRange:删除指定时间范围内的历史记录。

例子如下:

chrome.history.deleteRange(
    { startTime: Date.now() - 24 * 60 * 60 * 1000, endTime: Date.now() },
    () => console.log('最近一天的历史记录已删除')
);

虽然 chrome.history 没有监听新增或删除历史记录的直接事件,但你可以通过配合其他 API,例如 chrome.tabs.onUpdated,间接获取用户浏览行为:

chrome.tabs.onUpdated.addListener((tabId, changeInfo, tab) => {
    if (changeInfo.url) {
        console.log(`用户访问了新页面: ${changeInfo.url}`);
    }
});

除此以外,我们还可以配合搜索条件,构建复杂过滤功能。例如,只查询访问量高于一定次数的记录:

chrome.history.search({ text: '', startTime: Date.now() - 30 * 24 * 60 * 60 * 1000 }, (results) => {
    const frequentVisits = results.filter((item) => item.visitCount > 5);
    console.log(frequentVisits);
});

下载管理

浏览器的下载管理功能跟历史记录的 API 非常相似,大部分的能力和应用都是相通的。

基础功能
  1. 下载查询::使用 chrome.downloads.search 进行下载记录的查询,支持按时间、文件类型等条件筛选。
chrome.downloads.search({ query: '', startTime: Date.now() - 7 * 24 * 60 * 60 * 1000 }, (results) => {
    console.log(results); // 输出最近一周的下载记录
});
  1. 任务管理::控制下载任务,例如暂停、取消某个下载任务。

- 暂停下载:

chrome.downloads.pause(downloadId, () => {
    console.log('下载任务已暂停');
});
  • 取消下载:
chrome.downloads.cancel(downloadId, () => {
    console.log('下载任务已取消');
});

记录清理:使用 chrome.downloads.erase 清除过期或特定时间段的下载记录。

chrome.downloads.erase({ startTime: Date.now() - 30 * 24 * 60 * 60 * 1000 }, () => {
    console.log('30天前的下载记录已清除');
});
实际应用
  1. 自动分类助手:插件根据文件类型自动将下载的内容分类保存到不同的文件夹,比如文档、图片、视频等。
  2. 任务监控工具:提供实时的下载任务进度提醒,并在完成后自动触发文件操作。

代码示例:

chrome.downloads.search({}, function(downloads) {
  const categorized = downloads.reduce((acc, item) => {
    const ext = item.filename.split('.').pop();
    acc[ext] = acc[ext] || [];
    acc[ext].push(item);
    return acc;
  }, {});
  console.log('分类后的下载记录:', categorized);
});

存储管理

Chrome 存储 API 提供了强大的支持,用于插件中数据的持久化和跨设备同步。它确保用户的设置和数据能够在不同设备间保持一致,同时支持实时监听功能,方便插件及时响应数据变化,提升用户体验和数据管理的效率。

核心功能

  1. 本地存储chrome.storage.local 提供持久化存储功能,用于存储与扩展功能相关的数据,支持离线访问。

    chrome.storage.local.set({ key: 'value' }, function() {
        console.log('数据已存储至本地');
    });
    
  2. 跨设备同步:chrome.storage.sync 实现扩展配置的云端同步,确保数据在不同设备间保持一致。

    chrome.storage.sync.set({ key: 'value' }, function() {
        console.log('数据已同步到云端');
    });
    
  3. 实时监听chrome.storage.onChanged 监听存储数据的变化,一旦有变化,可以触发响应动作。

    chrome.storage.onChanged.addListener((changes, areaName) => {
        console.log('存储数据已变化:', changes, areaName);
    });
    

实际应用场景

  1. 偏好设置管理器:存储用户个性化设置,例如主题、语言、清理规则等,方便用户跨设备同步和管理。
  2. 数据持久化工具::用户工作记录或任务状态在不同设备间保持一致,提升跨设备使用体验。

个人设置

以上 3 个 API 我主要用来清理历史记录和下载记录的。通过自己设定的一些策略来完成个性化需求的实现。

下面是我定义的几个相关的方法:


// 删除历史记录  
function deleteHistory(page) {  
    chrome.browsingData.removeHistory({  
        url: page.url  
    }, function () {  
        if (chrome.runtime.lastError) {  
            console.error(`delete Error history:`, chrome.runtime.lastError);  
        } else {  
            console.log("delete page:", page.url);  
        }  
    });  
    // chrome.history.deleteUrl({url: page.url});  
    chrome.history.deleteUrl({url: page.url}, function () {  
        if (chrome.runtime.lastError) {  
            // console.error(`delete Error history:`, chrome.runtime.lastError);  
        } else {  
            console.log("delete page:", page.url);  
        }  
    });  
}  

function deleteDownlaods() {  
    chrome.downloads.search({}, (downloads) => {  
        downloads.forEach((download) => {  
            // 只删除已完成的下载记录  
            if (download.state === 'complete') {  
                chrome.downloads.erase({id: download.id}, () => {  
                    // chrome.downloads.removeFile(download.id, () => {  
                    if (chrome.runtime.lastError) {  
                        if (chrome.runtime.lastError.message !== "Download file already deleted") {  
                            console.error("Error removing download:", chrome.runtime.lastError.message);  
                        }  
                    } else {  
                        console.log(`Removed download: ${download.id}`);  
                    }  
                });  
            } else {  
                console.log(`Skipping download: ${download.id} (state: ${download.state})`);  
            }  
        });  
    });  
}

// 监听历史记录变化  
chrome.history.onVisitRemoved.addListener(function (removed) {  
    console.log("Removed visit:", removed);  
});  

function clearHistoryRecord() {  
    const endTime = Date.now() - (5 * 24 * 60 * 60 * 1000);  
    chrome.history.deleteRange({  
        startTime: 0,//含义是删除所有历史记录  
        endTime: endTime//删除5天前的历史记录  
    }, function () {  
        console.log(`Deleted history older than 5 days`);  
    });  
}

其实一个比较复杂的就是删除最近的历史记录的方法,主要区分了一些常用网站的域名:

function clearRecentRecord() {  
    console.info("clear recent record");  
    // start = Date.now() - 1000 * 60 * 60 * 12;// 12 小时前  
    end = Date.now() - 1000 * 60 * 10;// 10 分钟前  
    chrome.history.search({  
        text: "",  
        startTime: 0,//含义是删除所有历史记录,0表示从1970年1月1日开始  
        endTime: end,  
        maxResults: 1200  
    }, function (data) {  
        let domainMap = {};  
        let countMap = {};  
        console.info("history data:", data.length);  
        for (let i = 0; i < data.length; i++) {  
            page = data[i];  
            let domain = page.url.split('/')[2];  
            let countUrl = domain;  
            const parts = domain.split('.');  
            if (parts.length > 2) {  
                countUrl = parts.slice(-2).join('.');// 只取域名后两部分,-2表示倒数第二个,join表示拼接  
            }  
            if (shouldDeletePage(domain)) {  
                console.info("should delete page:", domain);  
                deleteHistory(page);  
                continue;  
            }  
            if (delete2Domain.includes(countUrl)) {  
                deleteHistory(page);  
                continue;  
            }  
            // console.info("page:", page);  
            // console.log("url:", domain, page.url);            if (!domainMap[domain]) {// 如果不存在,则初始化为1  
                domainMap[domain] = 1;  
            } else {  
                domainMap[domain]++;// 记录域名出现的次数  
            }  
            if (!countMap[countUrl]) {// 如果不存在,则初始化为1  
                countMap[countUrl] = 1;  
            } else {  
                countMap[countUrl]++;// 记录url出现的次数  
            }  
            if (keep2Domains.includes(countUrl)) {  
                if (domainMap[domain] > 5) {  
                    deleteHistory(page);  
                }  
            } else {  
                if (countMap[countUrl] > 1) {  
                    deleteHistory(page);  
                }  
            }  
        }  
        console.info("map:", domainMap);  
    });  
}

使用定时任务来定时执行,这个放在下期内容分享,专门分享一下定时任务的处理方式。

FunTester 原创精华

【连载】从 Java 开始性能测试

如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
暂无回复。
需要 登录 后方可回复, 如果你还没有账号请点击这里 注册