0

現在の URL ではなく、最後にアクセスした URL を取得しています。(site.com にアクセスしてから site2.com に移動すると、取得する URL は「site.com」になり、site2.com を更新した後、正しい URL が取得されます。

ここの回答に基づいて:
Google Chrome Extension get page information
クロム拡張機能で現在の URL を表示する

私はこのコードを思いつきました:

マニフェスト.json

{
  "manifest_version": 2,

  "browser_action": {
    "default_popup": "action.html"
  },
  "content_scripts": [
    {
      "matches": ["http://*/*", "https://*/*"],
      "js": ["content.js"],
      "run_at": "document_end"
    }
  ],
  "background": {
    "scripts": ["background.js"]
  },
  "permissions": [
    "tabs",
    "unlimitedStorage",
  ]
}

content.js

chrome.extension.sendRequest({method: "getUrl"}, function(response) {
  console.log(response.data);
});

background.js

chrome.extension.onRequest.addListener(function(request, sender, sendResponse) {
    if(request.method == "getUrl") {
      chrome.tabs.query({ currentWindow: true, active: true }, function (tabs) {
        currentUrl = tabs[0].url;
      });
      sendResponse({data: currentUrl});
    }
    else
      sendResponse({}); // snub them.
});

また、このコードを content.js に直接配置しようとしましたが、エラーが発生し、background.js で URL が に設定されていchrome://extensions/ます。

chrome.tabs.query({ currentWindow: true, active: true }, function (tabs) {
  currentUrl = tabs[0].url;
});

これを行う正しい方法は何ですか?

4

1 に答える 1

4

まず第一に: chrome.extension.sendRequest/onRequestは非推奨です。代わりにchrome.runtime.sendMessage / onMessageを使用してください。
また、可能な限り、バックグラウンド ページよりもイベント ページを優先してください。ほとんどの場合、背景ページをイベント ページに変換するのにほとんど時間がかかりませんが、リソースを大幅に節約できます。

問題:
chrome.tabs.queryは非同期です。これは、呼び出されると、リクエストを初期化し、その実行を完了して、スクリプトの次の部分が実行されることを意味します。リクエストが完了すると、登録されたコールバック関数が実行されます。したがって、これはあなたの場合に起こります:

  1. にアクセスしhttp://www.site1.comます。
  2. chrome.tabs.query({...}, callback)が実行されます (コールバックがまだ実行されていないことに注意してください)。
  3. sendResponse({data: currentUrl})実行されます (この時点currentUrlでは定義されていないことに注意してください)。
  4. chrome.tabs.queryのリクエストが完了し、コールバック関数が実行され、設定されますcurrentUrl = "http://www.site1.com"(ただし、手遅れになってからのみ)。
  5. にアクセスしhttp://www.site2.comます。
  6. chrome.tabs.query({...}, callback)が実行されます (コールバックがまだ実行されていないことに注意してください)。
  7. sendResponse({data: currentUrl})が実行されます (この時点でcurrentUrlはまだhttp://www.site1.com手順 4 と同じであることに注意してください)。
  8. chrome.tabs.queryのリクエストが完了し、コールバック関数が実行され、設定されますcurrentUrl = "http://www.site2.com"(これも遅すぎる場合のみ)。

解決策:
(A)
ロジックをコールバック内に移動します。
(注:コールバック (つまりsendResponse) が非同期的に呼び出される場合は常に、onMessageリスナーが を返す必要がありtrueます。)

chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
    if(request.method && (request.method == "getURL")) {
        if (sendResponse) {
            chrome.tabs.query({
                currentWindow: true,
                active: true
            }, function(tabs) {
                if (tabs.length > 0) {
                    sendResponse({ data: tabs[0].url });
                }
            });
            /* Since 'sendResponse' is to going be called
             * asynchronously, it is necessary to return 'true' */
            return true;
        }
    } else {
        // Do not talk to strangers !!!
    }
});

(B)
あなたのケースではさらに単純で、 onMessagesenderリスナーのパラメーターには、URL 情報を含むフィールドが含まれています。例えば:tab

chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
    if(request.method && (request.method == "getURL") && sendResponse) {
        sendResponse({ data: sender.tab.url });
    }
});

(C)
コンテンツ スクリプトのコンテキストで URL のみが必要な場合は、コンテンツ スクリプトlocation.href内から使用してみませんか?

于 2013-11-06T11:26:26.587 に答える