Як використовувати jQuery в хромованому розширенні?


128

Я пишу хромоване розширення. І я хочу використовувати 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 у своє розширення?

Я спробував запустити jQuery разом із файлом work.js з background.jsфайлу.

// 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 працює навіть до jQuery (або інших бібліотек, які я можу додати в майбутньому).

І я також хотів би знати, що є правильним і найкращим способом використання сторонніх бібліотек у своєму хромовому розширенні.


2
Правильний шлях - це піти ваніль!
bjb568

Якщо ви шукаєте, як додати jQuery до спливаючого розширення (як я), дивіться це запитання: stackoverflow.com/questions/12035242/…
Pro Q

Відповіді:


124

Ви повинні додати свій сценарій jquery до свого проекту для розширення хрому та до backgroundрозділу свого manifest.json таким чином:

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

Якщо вам потрібен jquery у content_scripts, його також потрібно додати в маніфест:

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


7
Ну що ви точно маєте на увазі You have to add your jquery script to your chrome-extension project? Я зробив це: manifest.json: "background": { `" scriptpts ": [" thirdParty / jquery-2.0.3.js "," background.js "],` `" persistent ": false``}, `і я завантажив jQuery в папку ThirdParty. Однак я досі не можу використовувати jQuery. Це дає помилку: Uncaught ReferenceError: $ is not defined мій додав це до мого work.jsфайлу для тестування. $("body").html("Foo!");
Ішан

Наведений вище коментар виглядає як безлад, але при додаванні коментарів попередній перегляд не показаний. Пробачте, будь ласка, за це.
Ішан

Я маю на увазі додати його до папки з розширенням для Chrome. Як /home/you/chromexetension_source_files/thirdParty/jquery-2.0.3.js. Ви повинні зробити те ж саме з вашим work.js.
Ніко

1
Я намагався робити те, що ти сказав. Але я все одно отримую ту саму помилку, що не можу отримати доступ до jquery з мого work.jsфайлу. Uncaught ReferenceError: $ is not defined. Якщо можете, можете, будь-ласка, завантажити де-небудь робочий приклад. Просто простий приклад, як робити "$ (" body "). Html (" Foo! "); ' у work.js.
Ішан

7
У мене також були проблеми з отриманням jQueryчи $визнанням. Виявилось, я посилався на jQuery останнім у маніфестному масиві. Коли я поставив це першим, це визнали.
БенР

18

Дуже просто зробити наступне:

додайте наступний рядок у свій manifest.json

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

Тепер ви можете безкоштовно завантажити jQuery безпосередньо з URL-адреси

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

Джерело: google doc


1
Що робити, якщо у вас є кілька сценаріїв для завантаження?
ще

1
Чудова відповідь, якщо ви хочете завантажити свій скрипт з віддаленого сервера (що фактично вимагає довірити віддаленому серверу розширення та все, до чого він має доступ).
Натаніел Верхаарен

1
@NathanielVerhaaren Це розумне питання, але його можна пом'якшити, перевіривши джерело за допомогою subresource integrity(SRI).
Ден Аткінсон

13

І це працює чудово, але я переживаю, чи сценарії, додані до виконання таким чином, виконуються асинхронно. Якщо так, то може статися, що 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оскільки це поверне обіцянку.


Перший метод геніальний. Як хтось, хто не знає багато JavaScript, я ніколи такого не вважав.
FriskySaga

11

Крім уже згаданих рішень, ви можете також завантажувати 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


3
Це найкращий спосіб ... Вам не потрібна частина html.
c-an

1

У моєму випадку отримано робоче рішення через перехресні документи (XDM) та розширення Chrome onclick замість завантаження сторінки.

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!')
        }
    }
);
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.