Chrome外掛開發入門

Tuzilow發表於2021-04-18

最近學習了Chrome外掛的開發,總體來說上手還是很容易的,因為瀏覽器外掛本質上依舊是網頁,寫幾個demo基本就瞭解了他的開發過程。

什麼是Chrome外掛

正如開頭所說的,Chrome外掛實際上就是一個網頁,由HTML、CSS、JS、圖片等資源組成,與網頁不同的是,Chrome外掛是用來增強瀏覽器功能的,同時它還有一套屬於自己的開發規則和API。

每個外掛都由不同的元件構成,這些元件大都包括background scripts,content scripts,options page,UI以及各種邏輯檔案,當然,這些檔案是否需要是根據外掛的功能所決定的。

接下來我將通過開發一個獲取頁面圖片並儲存的外掛來介紹如何開發一個Chrome外掛。

獲取頁面上的圖片

首先,我們需要一個目錄來存放這個外掛的各個檔案。

建立manifest

manifest.json是一個Chrome外掛必不可少的檔案,它包含了你外掛的所有資訊。

{
  "name": "獲取圖片",
  "description": "獲取頁面上的所有圖片",
  "version": "1.0",
  "manifest_version": 3
}

只要在目錄中包含manifest.json,這個目錄就可以被作為一個Chrome外掛新增到Chrome當中。

  1. 在瀏覽器位址列中輸入chrome://extensions,回車以開啟瀏覽器的擴充套件程式介面
  2. 開啟開發人員模式
  3. 點選載入已解壓的擴充套件程式,選擇manifest檔案所在的目錄

這樣我們就成功安裝了一個擴充套件,接下來我們要在此基礎上完善它。

使用者介面

一個外掛可以有多種形式的使用者介面,這裡我們選擇彈出層作為使用者介面,在外掛根目錄下建立一個popup.html,這個頁面需要包含兩個按鈕分別用來觸發獲取圖片和儲存圖片的事件,以及一個用來展示圖片的盒子。

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <style>
      body,
      img {
        width: 400px;
      }
    </style>
  </head>
  <body>
    <button id="get">獲取</button>
    <button id="save">儲存</button>
    <div id="app"></div>
  </body>
</html>

注意,如果在popup.html中有中文出現,一定要在head標籤中新增<meta charset="UTF-8" />,以防止出現亂碼。

建立完成後,我們需要在manifest.json中宣告該頁面,以保證瀏覽器能夠正確的讀取到它。新增一個action物件,同時將popup.html設定為該物件的default_popup

{
  "name": "獲取圖片",
  "description": "獲取頁面上的所有圖片",
  "version": "1.0",
  "manifest_version": 3,
  "action": {
    "default_popup": "popup.html",
  },
}

為了讓我們的外掛像個正經的外掛,給他新增上圖示。我們需要準備16x16、32x32、48x48以及128x128四種大小的圖示圖片,將它們放到目錄中,之後將它們的路徑寫入manifest.json中。

{
  "name": "獲取圖片",
  "description": "獲取頁面上的所有圖片",
  "version": "1.0",
  "manifest_version": 3,
  "action": {
    "default_popup": "popup.html",
    "default_icon": {
      "16": "/images/logo16.png",
      "32": "/images/logo32.png",
      "48": "/images/logo48.png",
      "128": "/images/logo128.png"
    }
  },
}

為了讓圖示能夠在擴充套件程式管理頁面顯示,我們還需要新增一個icons物件。

{
  "name": "獲取圖片",
  "description": "獲取頁面上的所有圖片",
  "version": "1.0",
  "manifest_version": 3,
  "action": {
    "default_popup": "popup.html",
    "default_icon": {
      "16": "/images/logo16.png",
      "32": "/images/logo32.png",
      "48": "/images/logo48.png",
      "128": "/images/logo128.png"
    }
  }, 
  "icons": {
    "16": "/images/logo16.png",
    "32": "/images/logo32.png",
    "48": "/images/logo48.png",
    "128": "/images/logo128.png"
  }
}

點選擴充套件程式管理頁面中的更新按鈕,即可看到新增完使用者介面的外掛資訊了。

功能邏輯

之後我們要為外掛新增它應有的功能——獲取頁面圖片。

首先我們先簡單梳理一下需求:

  1. 點選popup.html中的獲取按鈕,拿到當前頁面的圖片
  2. 點選popup.html中的儲存按鈕,將拿到的圖片儲存下來

實際上我們的外掛與當前正在活動的頁面並不是同一個頁面,因此我們需要通過某種方式來將獲取圖片的js程式碼傳送到當前活動頁上,並且還需要這段js程式碼能夠在獲取到圖片之後將圖片傳送到popup.html中。

這裡我們就需要用到一開始提到的content scripts元件以及content script與popup之間通訊的API。content scripts簡單來說就是插入頁面的指令碼,雖說是插入頁面的指令碼,實際上它與頁面原本的js是分割開的,雙方不能獲取到對方的變數、函式等內容。不過content scripts還是可以獲取到dom的。

獲取圖片

首先新增一個content-script.js,這個指令碼主要有兩個功能,一是獲取圖片,二是監聽popup傳來的訊息,然後將獲取到的圖片作為回信傳回去。

chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
  // message的資料格式取決於傳送時的資料
  const { start } = message;

  if (start) {
    const images = document.getElementsByTagName('img');
    const imgSrcList = Array.from(images).map((img) => img.src);
    sendResponse(imgSrcList);
  }
});

之後我們要在manifest.json中宣告配置它

{
  ...
  "content_scripts": [
    {
      "matches": [
        "<all_urls>"
      ],
      "js": [
        "js/content-script.js"
      ]
    }
  ]
}

matches宣告瞭content scripts要注入的頁面,<all_urls>表示所有頁面,js屬性宣告瞭要注入的js指令碼,除此之外還有css屬性宣告要注入的css程式碼、run_at屬性宣告注入時機等都可以在官方文件中找到。

之後新增一個popup.js為介面上的按鈕註冊點選事件,並在popup.html中引入它

let srcList;
const getImageBtn = document.getElementById('get');

getImageBtn.addEventListener('click', async () => {
  // 獲取當前活動頁
  chrome.tabs.query({ active: true, currentWindow: true }, ([tab]) => {
    let message = { start: true };
    // 向content scripts傳送訊息
    chrome.tabs.sendMessage(tab.id, message, (res) => {
      srcList = Array.from(new Set(res));
      // popup中展示圖片
      const imgList = srcList.map((src) => `<img src="${src}" />`).join('');

      document.getElementById('app').innerHTML = imgList;
    });
  });
});

const saveImageBtn = document.getElementById('save');

saveImageBtn.addEventListener('click', () => {
  // 儲存圖片
});
<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <style>
      body,
      img {
        width: 400px;
      }
    </style>
  </head>
  <body>
    <button id="get">獲取</button>
    <button id="save">儲存</button>
    <div id="app"></div>
    <script src="./js/popup.js"></script>
  </body>
</html>

這裡我們需要注意,外掛要想和當前活動頁面通訊就需要首先獲取它的tabId,而要獲取當前活動頁面的tabId則需要給予外掛對應的許可權,因此我們需要在manifest.json中宣告所需要的許可權。

{
  ...
  "permissions": [
    "activeTab"
  ]
}

完成後更新一下外掛,然後開啟想要獲取圖片的頁面點選獲取按鈕即可(如果頁面已經提前開啟請重新整理一下)

儲存圖片

js可以通過a標籤設定href和download屬性來實現批量儲存圖片,但是這裡我們要通過呼叫chrome的download API來實現。

...

saveImageBtn.addEventListener('click', () => {
  chrome.tabs.query({ active: true, currentWindow: true }, ([tab]) => {
    if (!srcList) {
      document.getElementById('app').innerHTML = '未獲取圖片';
      return;
    }
      
    srcList.forEach((src) => {
      chrome.downloads.download({
        url: src,
      });
    });
  });
});

與獲取活動頁面相同,download API同樣也需要獲取許可權

{
  ...
  "permissions": [
    "activeTab",
    "downloads"
  ]
}

這樣一個獲取當前頁面圖片的外掛就完成了。

參考文章

相關文章