如何让 Chrome 历史忽略 URL 的一部分

How to Let Chrome History Ignore Part of URL

由于我的工作涉及浏览一个网站的很多项目,我需要知道哪些项目已经访问过哪些没有,以避免重复查看。

问题是这些项目的 URL 包括一些动态变化的垃圾参数。这意味着浏览器的历史记录对于识别哪些项目已经被查看几乎没有用。

这是 URL 的示例:

https://example.com/showitemdetail/?item_id=e6de72e&hitkey=true&index=234&cur_page=1&pageSize=30

只有 "item_id=e6de72e" 部分可用于识别每个项目。其他参数都是动态垃圾

我的问题是:如何让Chrome仅将"example.com/showitemdetail/?item_id=e6de72e"部分标记为已访问,而忽略其余参数?

请注意,我不想修改 URLs,因为这可能会警告网站服务器怀疑我在滥用他们的数据库。我希望垃圾参数仍然存在,但浏览器历史记录机制忽略它们。

我知道这并不容易。我提出了一个可能的解决方案,但不知道是否可以实施。是这样的:

步骤:1) 一个扩展后台脚本,用于从我打开的每个页面中提取 item_id,然后将其存储在一个字符串集合中。这个字符串集合应该保存在某个文件中。

步骤:2) 每次我打开一个包含各种项目列表的网页时,后台脚本都会验证每个 URL 是否包含与上述集合中的任何一个相匹配的字符串。如果是这样,URL 将自动添加到历史记录中。那么该项目自然会显示为已访问。

逻辑听起来还行吗?如果可以,如何通过简单的扩展来实现它?

当然,如果你有其他更巧妙的解决方案,我会非常有兴趣学习。

假设项目的 link 总是有 item_id,那会起作用,是的。

您需要执行以下步骤:

记录一个元素

  1. content_script 将代码添加到产品页面并对其进行跟踪。
  2. 在访问产品页面时:

    我。您可以通过检查 URL 参数(参见 one of these codes)来提取当前产品 ID。

    二。您使用 storage api to retrieve a certain stored variable, say: visited_products. This variable you need to implement it as a Set 因为它是处理唯一元素的最佳数据类型。

    三。使用 .has() 检查当前元素是否在列表中。如果是,则跳过它。如果一切都好,它应该总是新的,但检查一下也无妨。如果没有,则使用 add() 添加新的产品 ID(尽管 Set 不允许您添加重复的项目,因此您可以跳过检查并直接保存添加)。确保将其存储到 Chrome.

现在您已经注册了对产品的访问。

检查访问过的元素

  1. 如果需要,您可以再次使用 content_script 插入产品页面或所有页面。

  2. 你得到页面的所有 links document.querySelectorAll(). You could apply a CSS selector 就像:a[href*="example.com/showitemdetail/?item_id="] 这将 select 所有 link s 的 href 包含 URL 部分。

  3. 然后,您使用 for 循环迭代 link。在每次迭代中,您提取 item_id。可能,最简单的方法是:/(?:item_id=)(.*?)(?:&|$)/。这匹配所有以 item_id= 开头的字符(未捕获),直到它找到字符串的 & 或结尾(以先发生者为准,并且未捕获)。

  4. 抓取到id后,可以用.has()查看第一部分的Set是否在列表中

  5. 现在如何处理是否在列表中,就看你自己了。您可以隐藏访问过的元素。或者对它们应用不同的 CSS 类 或样式,以便轻松区分它们。

我希望这能给您一个良好的开端。也许你可以试一试,如果你不能让它工作,你可以提出一个新的问题,说明你在哪里卡住了。

非常感谢,fvbuendia。经过反复试验,我成功了。 我不会post所有的代码,但会给出一些提示供其他用户参考:

1) 要获取新打开网页的URL并提取ID,请使用chrome.tabs.onUpdated.addListener和extractedItemId = tab.url.replace(/..../, .... );

2) 然后使用 chrome.storage.local.set 和 chrome.storage.local.get 将 ID 保存到 storage.local。 ID 应保存到对象数组中。

  • 1)和2)应该写在后台脚本中

3) 每次打开item列表页面,后台都会调用content script中的一个函数,请求页面中所有的URL。像这样:

chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) {
 if(changeInfo.status == "complete") {
  if(tab.url.indexOf("some string typical of the item list page URL") > -1) {
   chrome.tabs.executeScript(null, { code: 'getalltheurls();' });
}  }
});

4)内容脚本中要执行的函数:

function getalltheurls() {
 var urls = [];
 var links = document.links;
  for (var i = 0; i < links.length; i++) {
   if(links[i].href.indexOf("some string typical of the item list URLs") > -1) { urls.push(links[i].href);}
  }
 chrome.runtime.sendMessage({ urls: urls });
    };

5) 后台接收URLs,然后使用

将它们转换为ID数组
idinlist = urls[i].replace(........)

6) 然后后台获取本地存储,使用chrome.storage.local.get,并检查这些ID是否在存储数组中。如果是这样,请将 URL 添加到历史记录中。

for (var i = 0; i < urls.length; i++) {
if (storedIDs.indexOf(idinlist) > -1 ) { chrome.history.addUrl({ url: urls[i] }); }
}