Bagaimana cara menggunakan jQuery di ekstensi chrome?

129

Saya sedang menulis ekstensi chrome. Dan saya ingin menggunakan jQueryekstensi saya. Saya tidak menggunakan halaman latar belakang apa pun , hanya skrip latar belakang .

Ini file saya:

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.jsFile saya hanya menjalankan file lain bernamawork.js

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

Logika utama ekstensi saya ada di dalam work.js. Isi yang menurut saya tidak penting di sini untuk pertanyaan ini.

Yang ingin saya tanyakan adalah bagaimana saya bisa menggunakan jQuery di ekstensi saya. Karena saya tidak menggunakan halaman latar belakang apa pun. Saya tidak bisa menambahkan jQuery begitu saja. Jadi bagaimana saya dapat menambahkan dan menggunakan jQuery ke dalam ekstensi saya?

Saya mencoba menjalankan jQuery bersama dengan work.js saya dari 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'
    });
});

Dan itu berfungsi dengan baik, tetapi saya memiliki kekhawatiran apakah skrip yang ditambahkan untuk dieksekusi dengan cara ini dijalankan secara asinkron. Jika ya maka bisa terjadi bahwa work.js berjalan bahkan sebelum jQuery (atau pustaka lain yang dapat saya tambahkan di masa mendatang).

Dan saya juga ingin tahu apa cara yang benar dan terbaik untuk menggunakan pustaka pihak ketiga, di ekstensi chrome saya.

Ishan
sumber
2
Cara yang benar adalah dengan menggunakan vanila!
bjb568
Jika Anda di sini mencari cara menambahkan jQuery ke ekstensi pop-up (seperti saya dulu), lihat pertanyaan ini: stackoverflow.com/questions/12035242/…
Pro Q

Jawaban:

125

Anda harus menambahkan skrip jquery Anda ke proyek ekstensi-chrome dan ke backgroundbagian manifest.json Anda seperti ini:

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

Jika Anda membutuhkan jquery di content_scripts, Anda harus menambahkannya juga di manifes:

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

Inilah yang saya lakukan.

Juga, jika saya ingat dengan benar, skrip latar belakang dijalankan di jendela latar belakang yang dapat Anda buka melalui chrome://extensions.

Nico
sumber
7
Nah, apa sebenarnya yang Anda maksud dengan You have to add your jquery script to your chrome-extension project? Saya melakukan ini: manifest.json: "background": { `" scripts ": [" thirdParty / jquery-2.0.3.js "," background.js "],` `" persistent ": false``}, `dan saya telah mengunduh jQuery ke folder thirdParty. Namun saya masih tidak bisa menggunakan jQuery. Ini memberikan kesalahan: Uncaught ReferenceError: $ is not defined saya menambahkan ini ke work.jsfile saya untuk pengujian. $("body").html("Foo!");
Ishan
Komentar di atas terlihat seperti berantakan tetapi saat menambahkan komentar pratinjau tidak ditampilkan. Mohon maafkan saya untuk itu.
Ishan
Maksud saya menambahkannya ke folder ekstensi-chrome Anda. Sukai /home/you/chromexetension_source_files/thirdParty/jquery-2.0.3.js. Anda harus melakukan hal yang sama dengan work.js.
Nico
1
Saya mencoba melakukan apa yang Anda katakan. Tetapi saya masih mendapatkan kesalahan yang sama karena tidak dapat mengakses jquery dari work.jsfile saya . Uncaught ReferenceError: $ is not defined. Jika bisa, dapatkah Anda mengunggah contoh yang berfungsi di suatu tempat. Hanya contoh sederhana seperti melakukan '$ ("body"). Html ("Foo!");' di work.js.
Ishan
7
Saya juga mengalami kesulitan untuk mendapatkan jQueryatau $dikenali. Ternyata saya mereferensikan jQuery terakhir di array manifes. Ketika saya mengutamakannya, itu diakui.
BenR
18

Sangat mudah, cukup lakukan hal berikut:

tambahkan baris berikut di manifest.json Anda

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

Sekarang Anda bebas memuat jQuery langsung dari url

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

Sumber: google doc

Vikas Bansal
sumber
1
Bagaimana jika Anda memiliki banyak skrip untuk dimuat?
lain
1
Jawaban yang bagus jika Anda ingin memuat skrip Anda dari server jarak jauh (yang secara efektif mengharuskan Anda mempercayai server jarak jauh dengan ekstensi Anda dan semua yang dapat diaksesnya).
Nathaniel Verhaaren
1
@NathanielVerhaaren Ini adalah poin yang masuk akal untuk diangkat, tetapi dapat dikurangi dengan memverifikasi sumber menggunakan subresource integrity(SRI).
Dan Atkinson
13

Dan itu berfungsi dengan baik, tetapi saya memiliki kekhawatiran apakah skrip yang ditambahkan untuk dieksekusi dengan cara ini dijalankan secara asinkron. Jika ya maka bisa terjadi bahwa work.js berjalan bahkan sebelum jQuery (atau pustaka lain yang dapat saya tambahkan di masa mendatang).

Itu seharusnya tidak menjadi perhatian: Anda mengantrekan skrip untuk dieksekusi dalam konteks JS tertentu, dan konteks itu tidak boleh memiliki kondisi balapan karena itu single-threaded.

Namun, cara yang tepat untuk menghilangkan kekhawatiran ini adalah dengan menyambung panggilan:

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

Atau, digeneralisasikan:

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

Atau, dijanjikan (dan dibawa lebih sesuai dengan tanda tangan yang tepat):

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

Atau, mengapa tidak, async/ await-ed untuk sintaks yang lebih jelas:

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

Catatan, di Firefox Anda bisa menggunakan browser.tabs.executeScriptkarena akan mengembalikan Promise.

Xan
sumber
Metode pertama sangat brilian. Sebagai seseorang yang tidak tahu banyak tentang JavaScript, saya tidak pernah memikirkan hal seperti itu.
FriskySaga
11

Terlepas dari solusi yang telah disebutkan, Anda juga dapat mengunduh jquery.min.jssecara lokal dan kemudian menggunakannya -

Untuk mengunduh -

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

manifest.json -

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

dalam html -

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

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

Arik Pamnani
sumber
3
Ini adalah cara terbaik ... Anda tidak memerlukan bagian html.
c-an
1

Dalam kasus saya mendapat solusi yang berfungsi melalui Cross-document Messaging (XDM) dan Executing ekstensi Chrome onclick alih-alih memuat halaman.

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!')
        }
    }
);
Ruslan Novikov
sumber