Come usare jQuery nell'estensione di Chrome?


128

Sto scrivendo un'estensione di Chrome. E voglio usare jQuerynella mia estensione. Non sto usando alcuna pagina di sfondo , solo uno script di sfondo .

Ecco i miei file:

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"
    }
}

Il mio background.jsfile esegue solo un altro file chiamatowork.js

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

La logica principale della mia estensione è dentro work.js. I contenuti di cui non credo contano qui per questa domanda.

Quello che voglio chiedere è come posso usare jQuery nella mia estensione. Dal momento che non sto usando alcuna pagina di sfondo. Non posso semplicemente aggiungere jQuery ad esso. Quindi, come posso aggiungere e usare jQuery nella mia estensione?

Ho provato a eseguire jQuery insieme al mio work.js dal background.jsfile.

// 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'
    });
});

E funziona benissimo, ma mi preoccupo se gli script aggiunti per essere eseguiti in questo modo vengano eseguiti in modo asincrono. Se sì, può succedere che work.js venga eseguito anche prima di jQuery (o di altre librerie che potrei aggiungere in futuro).

E vorrei anche sapere qual è il modo migliore e corretto di utilizzare librerie di terze parti, nella mia estensione di Chrome.


2
Il modo corretto è di andare alla vaniglia!
bjb568,

Se sei qui alla ricerca di come aggiungere jQuery a un'estensione pop-up (come lo ero io), vedi questa domanda: stackoverflow.com/questions/12035242/…
Pro Q

Risposte:


124

Devi aggiungere il tuo script jquery al tuo progetto con estensione chrome e alla backgroundsezione di manifest.json in questo modo:

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

Se hai bisogno di jquery in content_scripts, devi aggiungerlo anche nel manifest:

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

Questo è quello che ho fatto.

Inoltre, se ricordo bene, gli script in background vengono eseguiti in una finestra in background che è possibile aprire tramite chrome://extensions.


7
Bene, cosa intendi esattamente con You have to add your jquery script to your chrome-extension project? Ho fatto questo: manifest.json: "background": { `" scripts ": [" thirdParty / jquery-2.0.3.js "," background.js "],` `" persistent ": false``}, `e ho scaricato il jQuery nella cartella ThirdParty. Tuttavia, non riesco ancora a usare jQuery. Dà l'errore: il Uncaught ReferenceError: $ is not defined mio ha aggiunto questo al mio work.jsfile per il test. $("body").html("Foo!");
Ishan,

Il commento sopra sembra un disastro ma durante l'aggiunta dell'anteprima dei commenti non viene mostrato. Per favore, perdonami per questo.
Ishan,

Intendo aggiungerlo alla tua cartella con estensione di Chrome. Metti Mi piace /home/you/chromexetension_source_files/thirdParty/jquery-2.0.3.js. Dovresti fare la stessa cosa con il tuo work.js.
Nico,

1
Ho provato a fare quello che hai detto. Ma sto ancora ricevendo lo stesso errore di non riuscire ad accedere a jquery dal mio work.jsfile. Uncaught ReferenceError: $ is not defined. Se puoi, puoi per favore caricare un esempio funzionante da qualche parte. Solo un semplice esempio come fare '$ ("body"). Html ("Foo!");' in work.js.
Ishan,

7
Ho anche avuto problemi a ottenere jQueryo $essere riconosciuto. Ho scoperto che stavo facendo riferimento a jQuery per ultimo nell'array manifest. Quando l'ho messo per primo è stato riconosciuto.
BenR,

18

È molto semplice:

aggiungi la seguente riga nel tuo manifest.json

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

Ora sei libero di caricare jQuery direttamente dall'URL

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

Fonte: google doc


1
Cosa succede se hai più script da caricare?
un altro

1
Ottima risposta se si desidera caricare lo script da un server remoto (il che richiede effettivamente di fidarsi del server remoto con l'estensione e tutto ciò a cui ha accesso).
Nathaniel Verhaaren,

1
@NathanielVerhaaren Questo è un punto ragionevole da sollevare, ma può essere mitigato verificando la fonte usando subresource integrity(SRI).
Dan Atkinson,

13

E funziona benissimo, ma mi preoccupo se gli script aggiunti per essere eseguiti in questo modo vengano eseguiti in modo asincrono. Se sì, può succedere che work.js venga eseguito anche prima di jQuery (o di altre librerie che potrei aggiungere in futuro).

Questo non dovrebbe essere un problema: devi mettere in coda gli script per eseguirli in un determinato contesto JS, e quel contesto non può avere una condizione di competizione poiché è a thread singolo.

Tuttavia, il modo corretto per eliminare questa preoccupazione è concatenare le chiamate:

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

Oppure, generalizzato:

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

Oppure, promesso (e reso più in linea con la firma corretta):

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

Oppure, perché diamine no, async/ await-ed per una sintassi ancora più chiara:

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

Nota, in Firefox puoi semplicemente usare browser.tabs.executeScriptin quanto restituirà una promessa.


Il primo metodo è geniale. Come qualcuno che non conosce molto JavaScript, non ho mai considerato qualcosa del genere.
FriskySaga il

11

Oltre alle soluzioni già menzionate, puoi anche scaricare jquery.min.jslocalmente e quindi utilizzarlo -

Per il download -

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

manifest.json -

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

in html -

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

Riferimento - https://developer.chrome.com/extensions/contentSecurityPolicy


3
Questo è il modo migliore ... Non hai bisogno della parte html.
c-an,

1

Nel mio caso, ho ottenuto una soluzione funzionante tramite Cross-document Messaging (XDM) ed esecuzione dell'estensione Chrome onclick invece del caricamento della pagina.

manifest.json

{
  "name": "JQuery Light",
  "version": "1",
  "manifest_version": 2,

  "browser_action": {
    "default_icon": "icon.png"
  },

  "content_scripts": [
    {
      "matches": [
        "https://*.google.com/*"
      ],
      "js": [
        "jquery-3.3.1.min.js",
        "myscript.js"
      ]
    }
  ],

  "background": {
    "scripts": [
      "background.js"
    ]
  }

}

background.js

chrome.browserAction.onClicked.addListener(function (tab) {
  chrome.tabs.query({active: true, currentWindow: true}, function (tabs) {
    var activeTab = tabs[0];
    chrome.tabs.sendMessage(activeTab.id, {"message": "clicked_browser_action"});
  });
});

MyScript.js

chrome.runtime.onMessage.addListener(
    function (request, sender, sendResponse) {
        if (request.message === "clicked_browser_action") {
        console.log('Hello world!')
        }
    }
);
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.