Розширення Chrome: доступ до localStorage в контентному скрипті


157

У мене є сторінка параметрів, де користувач може визначити певні параметри, і він зберігає їх у localStorage: options.html

Тепер у мене також є скрипт вмісту, який повинен отримати параметри, визначені на options.htmlсторінці, але коли я намагаюся отримати доступ до localStorage із вмісту, він не повертає значення зі сторінки параметрів.

Як змусити мій скрипт вмісту отримати значення з localStorage, зі сторінки параметрів або навіть із фонової сторінки?




Відповіді:


233

Оновлення 2016:

Google Chrome випустив API зберігання: http://developer.chrome.com/extensions/storage.html

Це досить простий у використанні, як і інші API API, і ви можете використовувати його з будь-якого контексту сторінки в Chrome.

    // Save it using the Chrome extension storage API.
    chrome.storage.sync.set({'foo': 'hello', 'bar': 'hi'}, function() {
      console.log('Settings saved');
    });

    // Read it using the storage API
    chrome.storage.sync.get(['foo', 'bar'], function(items) {
      message('Settings retrieved', items);
    });

Щоб використовувати його, переконайтеся, що ви визначили його в маніфесті:

    "permissions": [
      "storage"
    ],

Існують методи "видалити", "очистити", "getBytesInUse" та слухач подій, щоб слухати змінене сховище "onChanged"

Використання нативного localStorage ( стара відповідь з 2011 року )

Сценарії вмісту виконуються в контексті веб-сторінок, а не на сторінках розширень. Тому, якщо ви отримуєте доступ до localStorage зі свого скрипта вмісту, це буде сховище з цієї веб-сторінки, а не зберігання на розширеній сторінці.

Тепер, щоб ваш скрипт вмісту читав ваше розширення сховища (де ви їх встановили на своїй сторінці параметрів), вам потрібно використовувати повідомлення для розширення .

Перше, що потрібно зробити, - це сказати своєму сценарію вмісту, щоб надіслати запит на розширення для отримання деяких даних, і ці дані можуть бути вашим розширенням localStorage:

contentcript.js

chrome.runtime.sendMessage({method: "getStatus"}, function(response) {
  console.log(response.status);
});

background.js

chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
    if (request.method == "getStatus")
      sendResponse({status: localStorage['status']});
    else
      sendResponse({}); // snub them.
});

Ви можете зробити API навколо цього, щоб отримати загальні дані localStorage до сценарію вмісту або, можливо, отримати весь масив localStorage.

Я сподіваюся, що допомогло вирішити вашу проблему.

Щоб бути фантазійним та загальним ...

contentcript.js

chrome.runtime.sendMessage({method: "getLocalStorage", key: "status"}, function(response) {
  console.log(response.data);
});

background.js

chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
    if (request.method == "getLocalStorage")
      sendResponse({data: localStorage[request.key]});
    else
      sendResponse({}); // snub them.
});

1
Очевидно, запитом може бути також {method: 'getStorage', key: 'status'}, і слухач відповів би відповідними даними.
— JC Inacio

Що робити, якщо я хочу, щоб все з LocalStorage було передано до розширення? Чи можу я писати sendResponse({data: localStorage});?
— Bibhas Debnath

Я трохи розгублений. Я хочу, щоб дані з моєї сторінки параметрів були доступні на сторінці background.html. Тож я роблю запит із фонової сторінки до contentcript? і contentcript може повернути дані локального зберігання? Дивіться це -> pastebin.com/xtFexFtc .. Чи правильно я це роблю?
— Бібхас Дебнат

7
Фонові сторінки та сторінки параметрів належать до одного контексту розширення, тому вам не потрібні сценарії вмісту або повідомлення. Ви можете зателефонувати localStorageбезпосередньо зі сторінки параметрів або скористатися chrome.extension.getBackgroundPageна сторінці параметрів.
— Мохамед Мансур

1
Це дивно. Я встановлюю кілька варіантів на сторінці параметрів і створюю контекстні меню на їх основі у фоновій сторінці. Справа в тому, що якщо я встановив змінну в localStorage на сторінці параметрів, вона не відображатиметься на фоновій сторінці негайно (тобто немає нового контекстного меню), якщо я не відключую і не вмикаю повторно розширення. Якась причина, про яку ви можете подумати?
— Bibhas Debnath

47

Іноді може бути краще використовувати API chrome.storage . Краще, ніж localStorage, оскільки ви можете:

  • зберігати інформацію зі свого скрипта вмісту без необхідності передачі повідомлень між скриптом вмісту та розширенням;
  • зберігайте свої дані як об’єкти JavaScript, не серіалізуючи їх до JSON ( localStorage зберігає лише рядки ).

Ось простий код, що демонструє використання chrome.storage. Сценарій вмісту отримує URL-адресу відвіданої сторінки та часової позначки та зберігає її, popup.js отримує її з області зберігання.

content_script.js

(function () {
    var visited = window.location.href;
    var time = +new Date();
    chrome.storage.sync.set({'visitedPages':{pageUrl:visited,time:time}}, function () {
        console.log("Just visited",visited)
    });
})();

popup.js

(function () {
    chrome.storage.onChanged.addListener(function (changes,areaName) {
        console.log("New item in storage",changes.visitedPages.newValue);
    })
})();

"Зміни" - це об'єкт, який містить старе і нове значення для даного ключа. Аргумент "AreaName" відноситься до назви області зберігання, або "локальної", "синхронізації" або "керованої".

Не забудьте оголосити дозвіл на зберігання в manifest.json.

manifest.json

...
"permissions": [
    "storage"
 ],
...

onChangedПодія вже надає дані в changesоб'єкті. Крім того, зверніть особливу увагу на namespaceчастину onChangedзаходу. Якщо ви зберігаєте щось, використовуючи chrome.storage.local.set, onChangedподія запускається, але читати за допомогою chrome.storage.sync.getмає мало сенсу.
— Rob W

Так, ти маєш рацію, відредагував мою відповідь. Очевидно, що ви можете використовувати chrome.storage.sync.get в інших сценаріях, але тут це справді зайве.
— Pawel Miech

У відповідь на перегляд 5 Вашої відповіді: changes.visitedPagesбуде визначено, якщо visitedPagesвона не була змінена. Введіть рядок, if (changes.visitedPages) { ... }щоб вирішити цю проблему.
— Rob W

7

Іншим варіантом було б використання API chromestorage. Це дозволяє зберігати дані користувачів з додатковою синхронізацією протягом сеансів.

Недоліком є ​​те, що він асинхронний.

https://developer.chrome.com/extensions/storage.html


@Jason, щодо всіх або нічого угод ?
— Pacerier
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.