Очистить сеанс и локальное хранилище для определенного домена из расширения Chrome

Можно ли очистить сеанс и локальное хранилище для определенного домена с помощью расширения Chrome?

Допустим, я хочу настроить таргетинг на sessionStorage или localStorage для somedomain.com. Как я это делаю сейчас:

function clearSessionSotorage(key) {
  /**
   * Clears the session storage value for the given key
   * @param string key The key whose value should be cleared, if not provided, all keys are cleared for the current domain
   */
   var code = key ? 'window.sessionStorage.clear(' + key + ')' : 'window.sessionStorage.clear()';
   chrome.tabs.executeScript(null, { code: code });
}

function clearLocalStorage(key) {
  /**
   * Clears the local storage value for the given key
   * @param string key The key whose value should be cleared, if not provided, all keys are cleared for the current domain
   */
  var code = key ? 'window.localStorage.clear(' + key + ')' : 'window.localStorage.clear()';
  chrome.tabs.executeScript(null, { code: code });
}

Это работает, пока активная вкладка открыта на странице somedomain.com.

Однако я хотел бы настроить таргетинг на определенные домены без необходимости отображать этот домен на активной вкладке.

Если это возможно, как я могу это сделать?

Я подумал о циклическом просмотре всех вкладок в поисках целевого URL-адреса, что было бы улучшением, но на самом деле я бы предпочел вариант, при котором домен вообще не должен быть активным.


person Wesley Smith    schedule 25.03.2016    source источник
comment
Я не думаю, что вы можете это сделать, поскольку вы заблокированы политикой того же происхождения. Скрипты на страницах, загруженных из домена1, не могут получить доступ к объектам хранилища из домена2.   -  person Arkantos    schedule 25.03.2016
comment
@Arkantos это расширение для Chrome, у него нет этого ограничения...   -  person smnbbrv    schedule 25.03.2016
comment
@smnbbrv точно, в этом контексте возможно многое, чего нет на обычной странице. Я надеюсь, что это один из тех, хороший улов на редактировании BTW   -  person Wesley Smith    schedule 25.03.2016
comment
@smnbbrv.. Приятно это знать. было бы полезно, если бы вы могли предоставить ссылку, объясняющую это. :)   -  person Arkantos    schedule 25.03.2016
comment
@DelightedD0D, как упоминалось здесь, clear() не будет принимает любые аргументы и очищает все элементы памяти. Если вы хотите удалить определенный элемент из хранилища на основе ключа, используйте вместо этого sessionStorage.removeItem(key)   -  person Arkantos    schedule 25.03.2016
comment
@Arkantos Я ценю твою готовность помочь. Проблема связана не с конкретными ключами, а с конкретными доменами. По замыслу Storage API нацелен на текущий активный домен. Я ищу технику, которая позволит мне использовать эту функцию при таргетинге на домен по моему выбору.   -  person Wesley Smith    schedule 25.03.2016
comment
@Arkantos из контекста расширения Chrome, мы можем вставлять код на страницы различными способами. Это позволяет нам обойти множество проблем с одинаковым происхождением и тому подобным, с которыми в противном случае можно было бы столкнуться.   -  person Wesley Smith    schedule 25.03.2016
comment
Собираетесь ли вы очистить хранилище сеансов для домена, который не активен ни на одной из вкладок, или вы просто хотите очистить хранилище сеансов на одной из вкладок, открытых в вашем окне, но не обязательно на активной вкладке?   -  person Arkantos    schedule 25.03.2016
comment
@Arkantos, в идеале, мне нужно очистить хранилище сеансов для всех вкладок, которые в настоящее время находятся в целевом домене, и локальное хранилище для самого домена.   -  person Wesley Smith    schedule 25.03.2016
comment
@DelightedD0D добавил решение, которому не нужно открывать вкладки...   -  person smnbbrv    schedule 25.03.2016


Ответы (4)


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

Когда ты сказал

Я бы предпочел вариант, при котором домен вообще не должен быть активным.

Похоже, вы забыли жизненный цикл sessionStorage, согласно Window.sessionStorage, sessionStorage будет очищаться при закрытии вкладки/браузера и не будет использоваться совместно между вкладками.

Открытие страницы в новой вкладке или окне приведет к инициации нового сеанса.

person Haibara Ai    schedule 25.03.2016
comment
А, хороший улов. Я действительно ошибся sessionStorage с тем, как работают файлы cookie сеанса. На самом деле мне нужно очистить как сеанс, так и локальное хранилище. Приношу свои извинения, изначально я пропустил это, потому что это не казалось важным, учитывая, что они используют один и тот же API. Но я не учел этот момент. +1 однако :) - person Wesley Smith; 25.03.2016
comment
@DelightedD0D, понятно... Что касается как localStorage, так и sessionStorage, я считаю, что единственный способ — зациклить все вкладки или вставить сценарии содержимого для определенных доменов. Тем не менее, мы могли бы подождать кого-нибудь еще, если у них есть идеи получше :) - person Haibara Ai; 25.03.2016
comment
Согласен, я думаю использовать цикл для sessionStorage и для localStorage, возможно, открыть новое окно для целевого URL-адреса без фокуса, ввести код, а затем закрыть окно - person Wesley Smith; 25.03.2016

Если вы хотите очистить sessionStorage/localStorage для определенного домена, который в данный момент открыт, но не активен в окне вашего браузера, вам необходимо выполнить некоторый скрипт в контексте этого домена.

Я думаю, вы можете сделать это, используя комбинацию chrome.tabs.query()(link1), а затем chrome.tabs.executeJavaScript() (link2), используя код в виде строки или имя файла Content Script.

chrome.tabs.query({
  'url' : 'target-domain.com'
});

chrome.tabs.executeScript({
    code: 'sessionStorage.clear()'
  });

(or)

chrome.tabs.executeScript(null, {file: "content_script.js"});

Для свойства url в tabs.query() вы можете использовать шаблоны, как указано здесь;

person Arkantos    schedule 25.03.2016

Как уже указывалось, есть способ с вкладками, где вы можете открыть вкладку и запустить там код. Но открытие/закрытие вкладок не очень хорошее решение...

После некоторого исследования у меня есть небольшое и вполне рабочее решение, использующее IFRAME вместо вкладок. Добавьте этот код в свой background.js:

// create a URL suffix to make it unique and make nearly impossible to hit the existing page
var suffix = 'chrome-run-on-domain-' + chrome.runtime.id;

// if the domain is blocking displaying pages in IFRAME, remove the restriction
chrome.webRequest.onHeadersReceived.addListener(function(details) {
  return {
    responseHeaders: details.responseHeaders.filter(function(e) {
      return e.name.toUpperCase() !== 'X-FRAME-OPTIONS';
    })
  };
}, { urls: [ '*://*/' + suffix ] }, ["blocking", "responseHeaders"]);

// finally the function which does the job: it adds an IFRAME to the background page
function injectScript(protocol, domain) {
  var iframe = document.createElement("iframe");

  iframe.src = protocol + '://' + domain + '/' + suffix;

  document.body.appendChild(iframe);
}

// run the code
injectScript('https', 'www.google.de');

Этот код уже составляет большую часть работы. Он создает iframe на вашей фоновой странице, которая безопасно попадает в домен вашего желания.

Затем вам нужно создать файл с изменениями, которые вы хотите запустить на странице:

// actually any action to do with a session/localStorage
sessionStorage.clear();
localStorage.clear();

// important, stops the page loading
// this prevents unnecessary images / css / js calls on that page
// and prevents js redirects
window.stop();

Теперь пришло время установить ссылки и разрешения в файле манифеста:

"background": {
  "scripts": [
    "background.js"
  ]
},
"content_scripts": [{
  "all_frames": true,
  "js": ["injectable.js"],
  "matches": ["*://*/chrome-run-on-domain-*"],
  "run_at": "document_start"
}],
"permissions": [
  "<all_urls>",
  "webRequest",
  "webRequestBlocking"
]

Что имеем в итоге: можно очистить localStorage и не только. Для этого не открываются новые вкладки, так что все проходит довольно гладко. Тем не менее, есть недостатки (все те же проблемы будут существовать при решении вкладок):

  1. нет защиты от перенаправления на стороне сервера (301/302/и т.д.). Если сервер ответит перенаправлением, его действительно нельзя перехватить.
  2. есть еще вызов сервера. Я попытался отменить запрос (если это сработает, недостатков вообще не было), но, к сожалению, хром не позволяет внедрить скрипт в отмененный запрос. window.stop() помогает здесь, но все же...

Он работает еще лучше с вашим первоначальным методом: вы просто сначала проверяете свои вкладки, есть ли страница с вашего домена, и если ее нет, используйте метод выше.

person smnbbrv    schedule 25.03.2016

Если ваше локальное хранилище исходит из iFrame, вы можете очистить его, втирая этот код в свою консоль.

$('.my_iframe')[0].contentWindow.localStorage.clear();
person Vibhor Dube    schedule 18.10.2017
comment
Этот вопрос не имеет ничего общего с фреймами, поэтому этот ответ действительно не подходит - person Wesley Smith; 18.10.2017