3

我正嘗試使用Chrome擴展程序歷史記錄API根據輸入的搜索詞獲取用戶的歷史記錄。但是在某些情況下,搜索無法正常工作。例如,當我輸入術語「bi」時,沒有給出結果,但是當我搜索「bit」時給出了一些結果,但不是全部,我通過在鉻歷史搜索中驗證了它並顯示了更多結果。這是歷史API如何工作,或者我做錯了什麼? 這裏是我的代碼 -Chrome擴展程序歷史記錄API不顯示所有結果?

window.onload = function() { 

function getHistory() { 
    var list = document.getElementById('list'); 
    var box = document.getElementById("box").value; 
    if (box === '') { 
    list.innerHTML = ''; 
    list.innerHTML = list.innerHTML + 'Nothing To Search.'; 
    } 
    else { 
    var microseconds = 1000 * 60 * 60 * 24 * 365 * 45; 
    var start = (new Date).getTime() - microseconds; 
    chrome.history.search({text: box, startTime: 0, maxResults: 50000}, function(data) { 
    if(Object.keys(data).length === 0) { 
    list.innerHTML = ''; 
     list.innerHTML = list.innerHTML + 'Nothing Found.'; 
    } 
    else { 
     list.innerHTML = ''; 
     data.forEach(function(page) { 
     list.innerHTML = list.innerHTML + '<li><p>'+page.title+'</p> <a href='+page.url+' target="_blank"><p>'+page.url+'</p></a></li> <hr>'; 
    }); 
    } 
    }); 
} 
} 

document.getElementById('search').onclick = getHistory; 
} 

謝謝。

回答

3

我看到了與我正在寫的擴展名相同的行爲。這真的很煩人,所以我開始瀏覽Chromium源代碼,以找出它的真實情況以匹配歷史記錄結果。

簡短的回答: 似乎從源代碼中,這種行爲是有意的,所以如果我們想要檢索的所有比賽,以我們堅持檢索所有歷史結果,並尋求在符合自己一個文本查詢JavaScript的。請注意,不要忘記仔細檢查開始/結束時間,並確保您的'maxResults'屬性足夠大,因爲這些屬性的錯誤值可能會給您帶來意想不到的結果。

龍答案

免責聲明:我沒有太多的C++的經驗,所以請糾正我的判斷,如果它是錯誤的。

以下函數(在history_backend.cc中)最終在調用chrome.history.search並調用非空文本查詢後調用。

bool URLDatabase::GetTextMatchesWithAlgorithm(
    const base::string16& query, 
    query_parser::MatchingAlgorithm algorithm, 
    URLRows* results) { 
    query_parser::QueryNodeVector query_nodes; 
    query_parser_.ParseQueryNodes(query, algorithm, &query_nodes); 

    results->clear(); 
    sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE, 
     "SELECT" HISTORY_URL_ROW_FIELDS "FROM urls WHERE hidden = 0")); 

    while (statement.Step()) { 
    query_parser::QueryWordVector query_words; 
    base::string16 url = base::i18n::ToLower(statement.ColumnString16(1)); 
    query_parser_.ExtractQueryWords(url, &query_words); 
    GURL gurl(url); 
    if (gurl.is_valid()) { 
     // Decode punycode to match IDN. 
     base::string16 ascii = base::ASCIIToUTF16(gurl.host()); 
     base::string16 utf = url_formatter::IDNToUnicode(gurl.host()); 
     if (ascii != utf) 
     query_parser_.ExtractQueryWords(utf, &query_words); 
    } 
    base::string16 title = base::i18n::ToLower(statement.ColumnString16(2)); 
    query_parser_.ExtractQueryWords(title, &query_words); 

    if (query_parser_.DoesQueryMatch(query_words, query_nodes)) { 
     URLResult info; 
     FillURLRow(statement, &info); 
     if (info.url().is_valid()) 
     results->push_back(info); 
    } 
    } 
    return !results->empty(); 
} 

傳遞給這個函數的算法query_parser::MatchingAlgorithm是指如下所示(從query_parser.h)枚舉,而從未明確地從我所知道的,所以這將是DEFAULT值設置。

enum class MatchingAlgorithm { 
    // Only words long enough are considered for prefix search. Shorter words are 
    // considered for exact matches. 
    DEFAULT, 
    // All words are considered for a prefix search. 
    ALWAYS_PREFIX_SEARCH, 
}; 

讀取默認選項上的註釋 -

算法本身「只有足夠長的時間被認爲是前綴搜索短 字被認爲是完全匹配的話。」 (query_parser.cc)將您的文本查詢和原始URL結果分解爲由空格或標點符號分隔的「單詞」列表,並檢查每對之間的「前綴匹配」。這就解釋了爲什麼如果您的歷史記錄中有多個網頁,並且網址中顯示「鉻」字樣,如果您搜索「hromium」,則不會得到任何結果,但是如果您搜索「chro」,則會得到所有結果。

在你的情況,我想搜索「比」不返回任何結果,因爲算法只查找確切的詞短期而言比賽,這意味着「比」將需要由空格或標點符號包圍URL /標題。如果你在谷歌搜索「bi」,然後再次查詢「bi」的歷史記錄,這是確認的。谷歌搜索歷史項將被匹配,因爲在谷歌的網址搜索「比」由標點符號和空格包圍:

https://www.google.ca/webhp?sourceid=chrome-instant&ion=1&espv=2&ie=UTF-8#q=

來源

+0

也不要忘記檢查重複項,因爲結果似乎包含了很多由於某種原因。 – jdunning

1

chrome.history.search並不一定意味着所有頁面都將被檢索。該文檔聲明它將搜索與查詢匹配的每個頁面的上次訪問時間。這可能是它爲什麼看起來不完整的原因。

至於爲什麼當有2個字符時沒有結果,當有3個字符時返回一些結果,我不能確定。這可能是由於其他參數設置的,如startTime。它應該有一個紀元時間值,並將其設置爲0將自1970年以後嘗試搜索(這可能是您打算執行的操作)。

+0

你是正確的,它只是搜索的最後一次訪問,但我不明白爲什麼有些術語並不返回任何東西。 – doctorsherlock

相關問題