Chrome Extension 歷史記錄、下載記錄和儲存管理

FunTester發表於2025-01-09

在現代瀏覽器擴充套件開發中,如何高效地管理歷史記錄、最佳化下載體驗,以及構建靈活的資料儲存方案,已經成為開發者們關注的焦點。今天,我們將深入探討 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 開始效能測試

  • 混沌工程、故障測試、Web 前端
  • 服務端功能測試
  • 效能測試專題
  • Java、Groovy、Go
  • 白盒、工具、爬蟲、UI 自動化
  • 理論、感悟、影片
如果覺得我的文章對您有用,請隨意打賞。您的支援將鼓勵我繼續創作!
打賞支援
暫無回覆。

相關文章