谷歌外掛Image downloader開發之 content script

對角發表於2016-12-08

自己運營了一個公眾號,在發文章的時候,需要在網上找一些圖,而有些網站的圖片可能隱藏在屬性或者背景圖中,要下載的時候經常審查元素,檢視原始碼,不太方便,最近在看一些谷歌外掛的api,便順手做了一個外掛Image downloader。原始碼放到了github上,順便學習並用了一下git。地址:github.com/yeyuqiudeng…

功能

Image downloader有下面幾個功能:

  • 收集所有的img標籤src的圖片連結
  • 收集所有的背景圖片連結
  • 可以根據定義的規則,收集標籤屬性中的連結
  • 支援圖片大小篩選
  • 顯示圖片的原始大小

預覽

谷歌外掛Image downloader開發之 content script

manifest.json

外掛用到谷歌外掛中的content script和popup。content script是注入到頁面中的js,需要在manifest.json配置注入頁面的規則,和注入那些js進入頁面。在這個外掛中,我的manifest.json是這樣的:

{
  "manifest_version": 2,
  "name": "Image downloader",
  "description": "圖片下載器,可以自定義屬性下載規則",
  "version": "1.0",
  "browser_action": {
    "default_icon": "icon16.png",
    "default_popup": "/popup/popup.html"
  },
  "permissions": [
    "tabs", 
    "downloads"
  ],
  "icons": {
        "16": "icon16.png",
        "48": "icon48.png",
        "128": "icon128.png"
    },
    "content_scripts": [{
        "matches": ["http://*/*", "https://*/*"],
        "js": ["common.js", "inject.js"]
    }]
}複製程式碼

content_scripts的配置表示要將common.js和inject.js注入到所有http和https的網站

common公共方法

在common裡我定義了兩個方法,一個用來顯示錯誤資訊,一個方法將圖片的相對路徑補全,在cdn地址前面加上http。

方法如下:

// 顯示錯誤資訊
const showMsg = (msg) => {
    let myDate = new Date();
    let now = myDate.toLocaleString();
    console.log(now + "【" + msg + "】");
};
// 拼接相對路徑及cdn
const concatUrl = (url, domain) => {
    let fullPath = url
    if (/^\/[^\/]+/.test(url)) { // 是否為相對路徑
        fullPath = domain + url
    }
    if (/^\/\//.test(url)) { // 是否為cdn
        fullPath = 'http:' + url
    }
    return fullPath
}複製程式碼

不太熟悉正則,也不知道寫得對不對。

其實這裡不需要再要一個common.js的檔案,只是上一次寫外掛的時候,公共的方法比較多,這次也將common.js留了下來。

content script

在注入頁面的JS中,主要是三個方法,分別用來收集img標籤的src地址,元素的背景圖片和自定義屬性規則的屬性值

收集img標籤的src值程式碼如下:

const getImgUrl = function() { // 獲取所有圖片的src值
    const allImg = document.querySelectorAll('img')
    const allImgUrl = []
    allImg.forEach((img) => {
        allImgUrl.push(concatUrl(img.src, domain))
    })
    return allImgUrl
}複製程式碼

其實就是獲取img標籤的集合,遍歷集合並獲取src的值,如果為相對路徑或cdn路徑,用concatUrl方法拼接成絕對路徑,最後組成一個由url地址組成的陣列。

獲取背景圖片的程式碼如下:

const getBackgroundImage = function() { // 獲取背景圖片
    const allDoms = document.querySelectorAll('*')
    const allBgImageUrl = []
    allDoms.forEach((element) => {
        let url = window.getComputedStyle(element)['background-image'].match(/url\("(.+)"\)$/)
        if (url && url[1]) {
            allBgImageUrl.push(concatUrl(url[1], domain))
        }
    })
    return allBgImageUrl
}複製程式碼

通過getComputedStyle方法來獲取所有元素的backgroundImage屬性值,並將url地址提取出來,如果一個backgroundImage中有多個url,只取第一個,後面的就捨棄了。這個方法也是返回一個由地址組成的陣列。

獲取配置屬性值的程式碼如下:

let configAttr = ['data-src'] // 配置的屬性
const getConfigAttrUrl = function() { //  獲取所有配置屬性的值
    const attrUrl = []
    if (configAttr.length > 0) {
        configAttr.forEach((attr) => {
            attrUrl.push(...getAllAttr(attr))
        })
    }
    return attrUrl
}
const getAllAttr = function(attr) { // 獲取對應屬性的值
    const attrs = []
    const allDoms = document.querySelectorAll('[' + attr + ']')
    allDoms.forEach((dom) => {
        const attrValue = dom.getAttribute(attr)
        attrs.push(concatUrl(attrValue, domain))
    })
    return attrs
}複製程式碼

configAttr用來配置需要獲取元素屬性的規則,這裡用了陣列來接收多個配置規則,預設收集所有元素的data-src屬性值。為什麼會內建這個規則呢?因為很多網站都用了這個屬性啊。

getAllAttr是根據傳進來的屬性獲取屬性值,getConfigAttrUrl是遍歷屬性規則,收集所有屬性規則下的所有屬性值,返回一個屬性值陣列。

圖片不會在進入頁面後馬上就進行收集,只會在使用者點選外掛時才開始收集當前頁面的圖片,並將收集到的資料傳送給popup處理。content script怎樣與popup互動,下一篇文章再說

相關文章