Розширення 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.