Как разрешить истории Chrome игнорировать часть 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» как посещенную и игнорировать остальные параметры?

Обратите внимание, что я НЕ хочу изменять URL-адреса, потому что это может вызвать тревогу у сервера веб-сайта, который заподозрит, что я злоупотребляю их базой данных. Я хочу, чтобы параметры мусора все еще были там, но механизм истории браузера их игнорировал.

Я знаю, что это нелегко. Я предлагаю возможное решение, но не знаю, можно ли его реализовать. Это вот так:

Шаг: 1) Фоновый скрипт расширения для извлечения item_id с каждой открываемой страницы, а затем сохранения его в наборе строк. Этот набор строк должен быть где-то сохранен в файле.

Шаг: 2) Каждый раз, когда я открываю веб-страницу со списком различных элементов, фоновый сценарий проверяет, содержит ли каждый URL-адрес строку, совпадающую с какой-либо из приведенной выше коллекции. Если это так, этот URL будет автоматически добавлен в историю. Тогда этот элемент, естественно, будет отображаться как посещенный.

Логика звучит нормально? И если да, то как это реализовать, сделав простое расширение?

Конечно, если у вас есть другие более изящные решения, мне было бы очень интересно узнать.


person M.X    schedule 13.04.2017    source источник


Ответы (2)


Предполагая, что ссылка на элементы всегда имеет item_id, это сработает, да.

Вам понадобятся следующие шаги:

Запись элемента

  1. content_script, который добавляет код на страницы продукта и отслеживает его.
  2. При входе на страницу продукта:

    я. Вы можете извлечь текущий идентификатор продукта, проверив параметры URL (см. один из этих кодов).

    II. Вы используете api хранилища для извлечения определенной хранимой переменной, например, visit_products. Эту переменную нужно реализовать как Set. поскольку это лучший тип данных для обработки уникальных элементов.

    III. Вы проверяете, находится ли текущий элемент в списке с помощью .has(). Если да, то пропускаете. Если все в порядке, он всегда должен быть новым, но проверить не помешает. Если нет, то вы используете add() для добавления нового идентификатора продукта (хотя Set не позволит вам добавлять повторяющиеся элементы, поэтому вы можете пропустить проверку и просто сохранить добавить его напрямую). Убедитесь, что вы сохранили его в Chrome.

Теперь вы зарегистрировали посещение продукта.

Проверка посещенных элементов

  1. Вы снова используете content_script для вставки на страницы продукта или на все страницы, если хотите.

  2. Вы получаете все ссылки страницы с document.querySelectorAll(). Вы можете применить CSS-селектор, например: a[href*="example.com/showitemdetail/?item_id="], который выберет все ссылки, href которых содержит эта часть URL.

  3. Затем вы повторяете ссылки с помощью цикла for. На каждой итерации вы извлекаете item_id. Наверное, самый простой способ: /(?:item_id=)(.*?)(?:&|$)/. Это соответствует всем символам, которым предшествует item_id= (не захвачено), пока не будет найден & или конец строки (в зависимости от того, что произойдет раньше, а не захвачено).

  4. С захваченным идентификатором вы можете проверить набор первой части с помощью .has(), чтобы увидеть, есть ли он в списке.

  5. Теперь о том, как обращаться с этим в списке, зависит от вас. Вы можете скрыть посещаемые элементы. Или примените к ним разные классы или стили CSS, чтобы их было легко различать.

Надеюсь, это даст вам преимущество. Может быть, вы можете попробовать, и, если вы не можете заставить это работать, вы можете открыть новый вопрос с тем, где вы застряли.

person nitobuendia    schedule 15.04.2017
comment
Спасибо, fvbuendia. Хотя мне потребуется некоторое время, чтобы понять, как использовать эти API, знание правильного пути все равно избавит меня от множества проб и ошибок. Сейчас я пойду на первоклассный курс. - person M.X; 17.04.2017
comment
Когда вы начнете пробовать и продвигаться вперед, не стесняйтесь возвращаться и задавать новые вопросы, чтобы мы могли помочь ;) Однако сначала вы должны попробовать! - person nitobuendia; 19.04.2017

Большое спасибо, fvbuendia. После некоторых проб и ошибок я сделал это. Я не буду выкладывать сюда все коды, но дам несколько советов для справки другим пользователям:

1) Чтобы получить URL-адрес недавно открытой веб-страницы и извлечь идентификаторы, используйте chrome.tabs.onUpdated.addListener и ExtractedItemId = tab.url.replace(/..../, ....);

2) Затем сохраните идентификаторы в storage.local, используя chrome.storage.local.set и chrome.storage.local.get. Идентификаторы должны быть сохранены в массиве объектов.

  • 1) и 2) должны быть прописаны в фоновом скрипте.

3) Каждый раз, когда открывается страница списка элементов, фон вызывает функцию в сценарии содержимого, запрашивая все 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) Фон получает URL-адреса, а затем преобразует их в массив идентификаторов, используя

idinlist = urls[i].replace(........)

6) Затем фон получает локальное хранилище, используя chrome.storage.local.get, и проверяет, находятся ли эти идентификаторы в хранимом массиве. Если это так, добавьте URL-адрес в историю.

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