Может ли chrome.storage сохранять «продвинутые» объекты, такие как дата или карта?

#google-chrome-extension #local-storage

#google-chrome-extension #локальное хранилище

Вопрос:

Я создал расширение Chrome, которое управляет историей Интернета, файлами cookie браузера и т.д. Я пытаюсь создать уведомление, если вы не запускаете его в течение недели, поэтому я использовал chrome.storage для сохранения метки времени всякий раз, когда вы используете расширение.


Вот мой код:

<popup.js >

 function clear()
{
chrome.browsingData.removeHistory({"since":0}, callback);
var now = new Date();
chrome.storage.local.set({key: now}, function() {
console.log('Value is set to '   now)
}
  

(обратный вызов — это пустая функция)


<background.js >

 chrome.storage.local.get(["key"], function(result) {
alert (result.key)
});
  

Когда я тестировал это, это дало мне:

 [object Object]
  

Почему этот код выдает мне это, а не временную метку, которую я сохранил?

Ответ №1:

Типы JSON

chrome.storage, как и расширение для обмена сообщениями в Chrome, поддерживает только типы, совместимые с JSON:

  • числа, но не BigInt
  • строки
  • логическое true и false
  • null но не undefined
  • объекты / массивы, состоящие из вышеуказанных простых типов
    • может быть вложенным
    • не может иметь циклических ссылок на себя
    • ключи должны быть строками, а не Symbol
    • неподдерживаемая часть будет удалена, поэтому сложный тип создаст {}

Он не поддерживает элементы DOM, экземпляры классов, Set, Map, RegExp, Date и так далее.
Они будут сохранены как {} .

Чтобы увидеть, что будет сохранено на самом деле, запустите это в своем коде или в консоли devtools:

 console.log(JSON.parse(JSON.stringify(obj)))
  

Решение для даты

Сохранить Date.now(), который является числом:

 chrome.storage.local.set({foo: Date.now()})
  

Чтобы воссоздать дату:

 chrome.storage.local.get('foo', data => {
   const date = new Date(data.foo);
   // use it here
})
  

Решение для Set / Map

Сохранение:

 chrome.storage.local.set({foo: [...map]})
  

Чтение:

 chrome.storage.local.get('foo', data => {
   const map = new Map(data.foo);
   // use it here
})
  

Альтернативы для медиа-объектов

  • Преобразовать в строку URI данных.
  • Преобразовать в ArrayBuffer и сохранить в IndexedDB.

P.S. Не используйте для объединения строк и объектов в console.log. Используйте , так: console.log('Value is set to', now)

Комментарии:

1. Как бы вы сохранили объект MediaStream? производный от navigator.mediaDevices.getUserMedia({video: true}) асинхронно возвращает объект MediaStream

2. Потоки не могут быть сохранены, но вы можете извлечь содержимое в виде URI данных или ArrayBuffer.