ส่วนขยายของ Chrome: การเข้าถึง localStorage ในสคริปต์เนื้อหา


157

ฉันมีหน้าตัวเลือกที่ผู้ใช้สามารถกำหนดตัวเลือกบางอย่างและมันบันทึกไว้ใน localStorage: options.html

ตอนนี้ฉันยังมีสคริปต์เนื้อหาที่ต้องการได้รับตัวเลือกที่กำหนดไว้ในoptions.htmlหน้า แต่เมื่อฉันพยายามเข้าถึง localStorage จากสคริปต์เนื้อหาจะไม่ส่งคืนค่าจากหน้าตัวเลือก

ฉันจะทำให้สคริปต์เนื้อหาของฉันรับค่าจาก localStorage จากหน้าตัวเลือกหรือแม้แต่หน้าพื้นหลังได้อย่างไร


1
ที่เกี่ยวข้อง: stackoverflow.com/questions/3033829/…
Shay Erlichmen

ที่เกี่ยวข้อง: stackoverflow.com/questions/4224039/…
Jason

ที่เกี่ยวข้อง: stackoverflow.com/questions/39768005/…
super1ha1

คำตอบ:


233

อัปเดตปี 2016:

Google Chrome เปิดตัว API การจัดเก็บข้อมูล: http://developer.chrome.com/extensions/storage.html

มันใช้งานง่ายเหมือน Chrome 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"

ใช้ native localStorage ( คำตอบเก่าจาก 2011 )

สคริปต์เนื้อหาทำงานในบริบทของหน้าเว็บไม่ใช่หน้าส่วนขยาย ดังนั้นหากคุณเข้าถึง localStorage จาก contentcript ของคุณจะเป็นที่เก็บข้อมูลจากหน้าเว็บนั้นไม่ใช่ที่เก็บข้อมูลส่วนขยาย

ตอนนี้จะให้สคริปต์เนื้อหาของคุณเพื่ออ่านการจัดเก็บส่วนขยายของคุณ (ที่คุณตั้งพวกเขาจากหน้าตัวเลือกของคุณ) คุณจำเป็นต้องใช้ส่วนขยายข้อความผ่าน

สิ่งแรกที่คุณทำคือบอกสคริปต์เนื้อหาของคุณให้ส่งคำขอไปยังส่วนขยายของคุณเพื่อดึงข้อมูลบางอย่างและข้อมูลนั้นสามารถเป็นส่วนขยายของคุณ localStorage:

contentscript.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

ฉันหวังว่าจะช่วยแก้ปัญหาของคุณ

เป็นแฟนซีและทั่วไป ...

contentscript.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 สามารถส่งคืนข้อมูล localStorage ได้หรือไม่ ดูสิ่งนี้ -> pastebin.com/xtFexFtc .. ฉันทำถูกไหม
Bibhas Debnath

7
หน้าพื้นหลังและหน้าตัวเลือกอยู่ในบริบทส่วนขยายเดียวกันดังนั้นคุณไม่จำเป็นต้องมีสคริปต์เนื้อหาหรือการส่งข้อความ คุณสามารถโทรlocalStorageโดยตรงจากหน้าตัวเลือกหรือใช้chrome.extension.getBackgroundPageจากหน้าตัวเลือก
Mohamed Mansour

1
นั่นเป็นเรื่องที่แปลก ฉันกำลังตั้งค่าตัวเลือกบางอย่างในหน้าตัวเลือกและสร้างเมนูบริบทขึ้นอยู่กับพวกเขาในหน้าพื้นหลัง สิ่งคือถ้าฉันตั้งค่าตัวแปรใน localStorage จากหน้าตัวเลือกมันไม่ได้รับการสะท้อนไปยังหน้าพื้นหลังทันที (เช่นไม่มีบริบทใหม่) เว้นแต่ฉันจะปิดการใช้งานและเปิดใช้งานส่วนขยายอีกครั้ง มีเหตุผลอะไรที่คุณนึกถึง?
Bibhas Debnath

47

บางครั้งมันอาจจะดีกว่าที่จะใช้ chrome.storage APIจะดีกว่า 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" หมายถึงชื่อของพื้นที่เก็บข้อมูลไม่ว่าจะเป็น 'local', 'sync' หรือ 'managed'

อย่าลืมประกาศสิทธิ์การจัดเก็บใน 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

อีกตัวเลือกหนึ่งคือใช้ Chromestorage API สิ่งนี้ช่วยให้การจัดเก็บข้อมูลผู้ใช้ด้วยการซิงค์เสริมระหว่างเซสชัน

ข้อเสียอย่างหนึ่งคือมันไม่ตรงกัน

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


@ Jason, เกี่ยวกับการทำธุรกรรมทั้งหมดหรือไม่มีอะไร?
Pacerier
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.