web-dev-qa-db-ja.com

chrome拡張でjQueryを使用する方法は?

chrome拡張機能を作成しています。そして、拡張機能でjQueryを使用したいと思います。背景ページではなく、背景スクリプトのみを使用しています。

ここに私のファイルがあります:

manifest.json

{
    "manifest_version": 2,

    "name": "Extension name",
    "description": "This extension does something,",
    "version": "0.1",

    "permissions": [
        "activeTab"
    ],

    "browser_action": {
        "default_icon": "images/icon_128.png"
    },

    "background": {
        "scripts": ["background.js"],
        "persistent": false
    },

    "icons": {
        "16": "images/icon_16.png",
        "48": "images/icon_48.png",
        "128": "images/icon_128.png"
    }
}

background.jsファイルは、work.jsという名前の別のファイルを実行するだけです

// Respond to the click on extension Icon
chrome.browserAction.onClicked.addListener(function (tab) {
    chrome.tabs.executeScript({
        file: 'work.js'
    });
});

私の拡張機能のメインロジックはwork.jsの中にあります。ここで私が考えていない内容は、この質問にとって重要です。

私が尋ねたいのは、拡張機能でjQueryを使用する方法です。私は背景ページを使用していないので。 jQueryを追加することはできません。では、jQueryを拡張機能に追加して使用するにはどうすればよいですか

background.jsファイルからwork.jsとともにjQueryを実行してみました。

// Respond to the click on extension Icon
chrome.browserAction.onClicked.addListener(function (tab) {
    chrome.tabs.executeScript({
        file: 'thirdParty/jquery-2.0.3.js'
    });
    chrome.tabs.executeScript({
        file: 'work.js'
    });
});

そして、それは正常に動作しますが、この方法で実行するために追加されたスクリプトが非同期で実行されているかどうか心配です。はいの場合、work.jsがbefore jQuery(または将来追加する可能性のある他のライブラリ)でさえ実行される可能性があります。

そして、私のchrome拡張でサードパーティのライブラリを使用するための正しい最良の方法を知りたいです。

101
Ishan

次のように、jqueryスクリプトをchrome-extensionプロジェクトとmanifest.jsonのbackgroundセクションに追加する必要があります。

  "background":
    {
        "scripts": ["thirdParty/jquery-2.0.3.js", "background.js"]
    }

Content_scriptsでjqueryが必要な場合は、マニフェストにも追加する必要があります。

"content_scripts": 
    [
        {
            "matches":["http://website*"],
            "js":["thirdParty/jquery.1.10.2.min.js", "script.js"],
            "css": ["css/style.css"],
            "run_at": "document_end"
        }
    ]

これは私がやったことです。

また、思い出すと、バックグラウンドスクリプトはバックグラウンドウィンドウで実行され、chrome://extensionsで開くことができます。

107
Nico

その非常に簡単な方法は次のとおりです。

mainfest.jsonに次の行を追加します

"content_security_policy": "script-src 'self' https://ajax.googleapis.com; object-src 'self'",

今、あなたはURLから直接jqueryをロードすることができます

  <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.2/jquery.min.js"></script>

ソース: google doc

14
Vikas Bansal

そして、それは正常に動作しますが、この方法で実行するために追加されたスクリプトが非同期で実行されているかどうか心配です。はいの場合、work.jsがjQuery(または将来追加される可能性のある他のライブラリ)の前でも実行される可能性があります。

特定のJSコンテキストで実行されるスクリプトをキューに入れ、そのコンテキストはシングルスレッドであるため競合状態になりません。

ただし、この懸念を解消する適切な方法は、呼び出しを連鎖させることです。

chrome.browserAction.onClicked.addListener(function (tab) {
    chrome.tabs.executeScript({
        file: 'thirdParty/jquery-2.0.3.js'
    }, function() {
        // Guaranteed to execute only after the previous script returns
        chrome.tabs.executeScript({
            file: 'work.js'
        });
    });
});

または、一般化:

function injectScripts(scripts, callback) {
  if(scripts.length) {
    var script = scripts.shift();
    chrome.tabs.executeScript({file: script}, function() {
      if(chrome.runtime.lastError && typeof callback === "function") {
        callback(false); // Injection failed
      }
      injectScripts(scripts, callback);
    });
  } else {
    if(typeof callback === "function") {
      callback(true);
    }
  }
}

injectScripts(["thirdParty/jquery-2.0.3.js", "work.js"], doSomethingElse);

または、約束された(そして適切な署名に沿ってさらに持ち込まれた):

function injectScript(tabId, injectDetails) {
  return new Promise((resolve, reject) => {
    chrome.tabs.executeScript(tabId, injectDetails, (data) => {
      if (chrome.runtime.lastError) {
        reject(chrome.runtime.lastError.message);
      } else {
        resolve(data);
      }
    });
  });
}

injectScript(null, {file: "thirdParty/jquery-2.0.3.js"}).then(
  () => injectScript(null, {file: "work.js"})
).then(
  () => doSomethingElse
).catch(
  (error) => console.error(error)
);

または、なぜそうではないのか、より明確な構文のためにasync/await- ed:

function injectScript(tabId, injectDetails) {
  return new Promise((resolve, reject) => {
    chrome.tabs.executeScript(tabId, injectDetails, (data) => {
      if (chrome.runtime.lastError) {
        reject(chrome.runtime.lastError.message);
      } else {
        resolve(data);
      }
    });
  });
}

try {
  await injectScript(null, {file: "thirdParty/jquery-2.0.3.js"});
  await injectScript(null, {file: "work.js"});
  doSomethingElse();
} catch (err) {
  console.error(err);
}

Firefoxでは、browser.tabs.executeScriptを使用するだけでPromiseが返されることに注意してください。

11
Xan

既に説明したソリューションとは別に、jquery.min.jsをローカルにダウンロードして使用することもできます-

ダウンロード用-

wget "https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"

manifest.json-

"content_scripts": [
   {
    "js": ["/path/to/jquery.min.js", ...]
   }
],

hTMLで-

<script src="/path/to/jquery.min.js"></script>

リファレンス- https://developer.chrome.com/extensions/contentSecurityPolicy

6
Arik Pamnani