簡體   English   中英

如何在 chrome 擴展中使用 jQuery?

[英]How to use jQuery in chrome extension?

我正在寫一個 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文件中運行 jQuery 和我的 work.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(或我將來可能添加的其他庫)之前運行。

而且我還想知道在我的 chrome 擴展中使用第三方庫的正確和最佳方式是什么。

您必須將 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打開的后台窗口中執行的。

它非常容易,只需執行以下操作:

在 manifest.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>

來源: 谷歌文檔

它工作正常,但我擔心添加以這種方式執行的腳本是否正在異步執行。 如果是,那么 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。

除了已經提到的解決方案之外,您還可以在本地下載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

就我而言,通過跨文檔消息傳遞 (XDM) 和執行 Chrome 擴展 onclick 而不是頁面加載獲得了一個可行的解決方案。

清單.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"
    ]
  }

}

背景.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!')
        }
    }
);

從清單 3 開始,不允許使用匿名函數(在后台也不行)。 Jquery.js 文件通常具有匿名函數您應該為它們設置一個名稱。

我手動下載了 jquery 並將其像 javascript 文件一樣導入到清單文件中。

maifest.json

"content_scripts": [
    {
      "matches": [...],
      "js": ["jquery-3.6.0.min.js", ...],
    }
  ]

folder sructure

extension
│   manifest.json
│   jquery-3.6.0.min.js
|   ...

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM