Ekstensi Chrome: mengakses localStorage dalam skrip konten

157

Saya memiliki halaman opsi di mana pengguna dapat menentukan opsi tertentu dan menyimpannya di localStorage: options.html

Sekarang, saya juga memiliki skrip konten yang perlu mendapatkan opsi yang didefinisikan di options.htmlhalaman, tetapi ketika saya mencoba mengakses localStorage dari skrip konten, itu tidak mengembalikan nilai dari halaman opsi.

Bagaimana cara membuat skrip konten saya mendapatkan nilai dari localStorage, dari halaman opsi atau bahkan halaman latar belakang?

pengguna476214
sumber

Jawaban:

233

Pembaruan 2016:

Google Chrome merilis API penyimpanan: http://developer.chrome.com/extensions/storage.html

Sangat mudah digunakan seperti API Chrome lainnya dan Anda dapat menggunakannya dari konteks halaman apa pun di dalam 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);
    });

Untuk menggunakannya, pastikan Anda mendefinisikannya di manifes:

    "permissions": [
      "storage"
    ],

Ada metode untuk "menghapus", "hapus", "getBytesInUse", dan pendengar acara untuk mendengarkan penyimpanan yang diubah "onChanged"

Menggunakan localStorage asli ( balasan lama dari 2011 )

Skrip konten dijalankan dalam konteks halaman web, bukan halaman ekstensi. Oleh karena itu, jika Anda mengakses Penyimpanan lokal dari script konten Anda, itu akan menjadi penyimpanan dari halaman web itu, bukan penyimpanan halaman ekstensi.

Sekarang, untuk membiarkan skrip konten Anda membaca penyimpanan ekstensi Anda (tempat Anda mengaturnya dari halaman opsi), Anda harus menggunakan pesan ekstensi .

Hal pertama yang Anda lakukan adalah memberi tahu skrip konten Anda untuk mengirim permintaan ke ekstensi Anda untuk mengambil beberapa data, dan data itu bisa menjadi ekstensi lokal Anda. Penyimpanan:

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.
});

Anda dapat melakukan API di sekitarnya untuk mendapatkan data localStorage generik ke skrip konten Anda, atau mungkin, mendapatkan seluruh array localStorage.

Saya harap itu membantu menyelesaikan masalah Anda.

Menjadi mewah dan generik ...

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.
});
Mohamed Mansour
sumber
1
Jelas, permintaan juga bisa {metode: 'getStorage', kunci: 'status'}, dan pendengar akan merespons dengan data yang sesuai.
JC Inacio
Bagaimana jika saya ingin semuanya dari localStorage dipindahkan ke ekstensi? Bisakah saya menulis sendResponse({data: localStorage});?
Bibhas Debnath
Saya sedikit bingung. Saya ingin data dari halaman opsi saya tersedia di halaman background.html .. Jadi saya membuat permintaan dari halaman Latar Belakang ke skrip isi? dan script isi dapat mengirim kembali data penyimpanan lokal? Lihat ini -> pastebin.com/xtFexFtc .. Apakah saya melakukannya dengan benar?
Bibhas Debnath
7
Halaman latar belakang dan halaman opsi termasuk dalam konteks ekstensi yang sama, jadi Anda tidak perlu skrip konten atau pesan. Anda dapat menelepon localStoragelangsung dari halaman opsi atau menggunakan chrome.extension.getBackgroundPagedari halaman opsi.
Mohamed Mansour
1
Itu aneh. Saya menetapkan beberapa opsi di halaman opsi dan membuat menu konteks berdasarkan pada mereka di halaman latar belakang. Masalahnya adalah, jika saya menetapkan variabel di localStorage dari halaman opsi, itu tidak bisa langsung direfleksikan ke halaman latar belakang (yaitu Tidak ada konteks baru), kecuali saya menonaktifkan dan mengaktifkan kembali ekstensi. Ada alasan yang bisa Anda pikirkan?
Bibhas Debnath
47

Terkadang mungkin lebih baik digunakan chrome.storage API. Lebih baik daripada penyimpanan lokal karena Anda dapat:

  • menyimpan informasi dari skrip konten Anda tanpa perlu menyampaikan pesan antara skrip konten dan ekstensi;
  • menyimpan data Anda sebagai objek JavaScript tanpa membuat serialkannya ke JSON ( localStorage only menyimpan string ).

Berikut adalah kode sederhana yang menunjukkan penggunaan chrome.storage. Skrip konten mendapatkan url dari halaman yang dikunjungi dan stempel waktu serta menyimpannya, popup.js mendapatkannya dari area penyimpanan.

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);
    })
})();

"Perubahan" di sini adalah objek yang berisi nilai lama dan baru untuk kunci yang diberikan. Argumen "AreaName" mengacu pada nama area penyimpanan, baik 'lokal', 'sinkronisasi' atau 'terkelola'.

Ingatlah untuk mendeklarasikan izin penyimpanan di manifest.json.

manifes. json

...
"permissions": [
    "storage"
 ],
...
Pawel Miech
sumber
The onChangedevent sudah menyediakan data dalam changesobjek. Selanjutnya, berikan perhatian khusus namespacepada onChangedacara tersebut. Jika Anda menyimpan sesuatu menggunakan chrome.storage.local.set, maka onChangedacara tersebut dipicu, tetapi membaca menggunakan chrome.storage.sync.gettidak masuk akal.
Rob W
Ya Anda benar, edit jawaban saya. Jelas Anda bisa menggunakan chrome.storage.sync.get di skenario lain, tapi ini memang berlebihan.
Pawel Miech
Menanggapi revisi 5 jawaban Anda: changes.visitedPagesakan tidak ditentukan jika visitedPagesbelum diubah. Bungkus garis if (changes.visitedPages) { ... }untuk menyelesaikan masalah ini.
Rob W
7

Pilihan lain adalah menggunakan API chromestorage. Ini memungkinkan penyimpanan data pengguna dengan sinkronisasi opsional di seluruh sesi.

Satu kelemahan adalah tidak sinkron.

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

Jason
sumber
@Jason, Bagaimana dengan transaksi semua atau tidak sama sekali ?
Pacerier