7

複数のドメイン間でこのデータにアクセスできるように、バックグラウンド (拡張機能) にデータを保存できるようにしたいと考えています。

私がやっていることはどこですか:

content-script.js

function setItem(name, data) {
    chrome.extension.sendMessage({ command: 'setItem', name: name, data: data });
}

function getItem(name) {
    chrome.extension.sendMessage({ command: 'getItem', name: name }, function(response) {
        return response;
    });
}

background-script.js

Storage.prototype.setObject = function(key, value) {
    this.setItem(key, JSON.stringify(value));
}

Storage.prototype.getObject = function(key) {
    var value = this.getItem(key);
    return value && JSON.parse(value);
}

chrome.extension.onMessage.addListener(function(request, sender, sendResponse) {
    switch (request.command) {
        case 'setItem':
            localStorage.setObject(request.name, request.data);
            return;
        case 'getItem':
            sendResponse(localStorage.getObject(request.name));
            return;
    }
});

しかし、getItemのコールバック内から戻ることができないため、成功しません。

コールバック内のデータを取得しますが、 getItemfunction(response) { }の戻り値として返すことはできません。

どうすればいいですか?

4

3 に答える 3

17

この2012年の質問は、最新の回答のために提起されました。じゃあ..

今のところ、適切な答えはchrome.storageAPIを使用することです。これは、拡張ページとコンテンツ スクリプトの両方にアクセスできる API であり、非同期ストレージを提供します。パーミッションが必要"storage"ですが、このパーミッションは警告を生成しません。

// Setting
chrome.storage.local.set({key: data}, function() {
  if(chrome.runtime.lastError) {
    console.error(
      "Error setting " + key + " to " + JSON.stringify(data) +
      ": " + chrome.runtime.lastError.message
    );
  }
});

// Getting
chrome.storage.local.get("key", function(data) {
  // Do something with data.key
});

ドキュメントのの部分も参照してください。

どちらの場合 (このアプローチ、またはバックグラウンドでメッセージを送信するアプローチ) も、呼び出しが非同期であるため、結果getData返す関数を作成できないことに注意してください。

いくつかのヒントとコツ:

  1. オブジェクトまたは配列をクエリとして渡すことにより、一度に複数の値を設定または取得できます。nullクエリを渡すことで、すべての値を読み取ることができます。

  2. get()次のようなクエリを渡すことにより、キーに値が保存されていない場合に備えて、操作のデフォルト値を指定できます。{key: defaultValue}

  3. chrome.storage.onChangedイベントでストレージへのすべての変更を通知できます。

  4. chrome.storage.local"unlimitedStorage"許可に従います。

  5. chrome.storage.syncChrome Sync が拡張機能で有効になっている場合、同じ Google アカウントにサインインしているすべてのプロファイルに値が伝達されます。ただし、クォータに注意してください。

  6. 絶対に同期アクセスが必要な場合は、chrome.storage. ただし、制限があります。同期コード ブロックでは、他のページからの変更でキャッシュが更新されず、一度非同期で値を読み取ってキャッシュに入力する必要があります。

于 2015-02-22T12:13:51.923 に答える
5

Content.js

var someVar = "hey hey!";

chrome.extension.sendRequest({method: "fromContentScript",greeting: someVar}, function(response) {

    console.log(response.data); // response back from BG

    if(response.who == 'bg'){ // checks if the response is from BG
            //Something happened ...
    }

    var responseFromBg = response.data; // the response incase we need to use the message sent back... in this case should be 'hey yourself'


});

Background.js

chrome.extension.onRequest.addListener(function(request, sender, sendResponse) {
  // From content script.
  if (sender.tab) {
    if (request.method == "fromContentScript"){

        localStorage.setItem("welcome-message",request.greeting); // in this case there will now be a localStorage variable called 'welcome-message' set with the value of 'hey hey!'. This will be viewable in the chrome:extensions page, click on the 'background.html / generated background.html' then view the 'Development Tools' or in Windows hit 'CTRL + SHIFT + I' and look at the 'LocalStorage' tab...

      sendResponse({who: "bg",data: "hey yourself"}); // this is the response sent back, 'who' tells the content page where is responding, so it can do something with the response if needed.
        }else{
      sendResponse({}); // snub them.
        }
  }
});

Manifest.json // マニフェストの問題である場合に備えて...ここに私のほとんどのものがあります..

{
  "name": "Name here",
  "version": "1",
  "manifest_version": 2,
  "description": "Enter desc here.",  
    "browser_action": {
    "default_icon": "img/icon16.png",
    "default_popup": "popup.html"
  },    
    "background": {
    "scripts": ["background.js"]
  },
  "permissions": [
    "tabs", "*://*/*"
  ],
    "icons": { "16": "img/icon16.png",
           "48": "img/icon48.png",
          "128": "img/icon128.png" },
  "content_scripts": [
    {
      "matches": ["*://*/*"],
      "js": ["js/jquery-1.7.2.min.js","content_script.js"],
      "run_at": "document_end"
    }
  ]
}

あなたの例を使ったでしょうが、今朝急いでいます。すべての変数をできる限り注意深く説明しようとしました - 申し訳ありません:(

于 2012-06-28T06:34:54.603 に答える
1

background-script.js:

chrome.extension.onMessage.addListener(function(request, sender, sendResponse) {
    switch (request.command) {
        case 'setItem':
            localStorage[request.name] = JSON.stringify(request.data));
            return;
        case 'getItem':
            var retValue;
            if (typeof(localStorage[request.name]) === 'string') {
                retValue = JSON.parse(localStorage[request.name]);
            }
            sendResponse(retValue);
            return;
        case 'deleteItem':
            if (typeof localStorage[request.name] !== 'undefined') {
                delete localStorage[request.name];
            }
            return;
    }
});

キーが localStorage にない場合、getItem は を返しundefinedます。このように関数を定義する代わりにgetItem、コールバックを使用してバックグラウンドにメッセージを送信し、コールバックが呼び出されたときに値を使用して何かを行う必要があります。function から値を返すことはできませんが、getItem呼び出されたときにコールバックで値を使用できます。

function getItem(name, callback) {
    chrome.extension.sendMessage({command: 'getItem', name: name}, function(response) {
        if (typeof(callback) === "function") {
            callback(response);
        }
    });
}
于 2015-02-23T16:45:33.423 に答える