記一次 aria2 chrome 擴(kuò)展的琢磨過程
目錄
1 查看全部代碼
2 起因
aria2 安裝在別的電腦上,有時想用 aria2 下載東西的時候,可以直接復(fù)制鏈接; 但部分文件需要 cookie,每次手動復(fù)制有點麻煩。 網(wǎng)上搜索 aria2 的 chrome 擴(kuò)展,也試用過,但覺得不太好用, 因為大部分?jǐn)U展勾選使用 aria2 下載后,下載時就直接發(fā)送 addUri 請求了; 不勾選 aria2 下載,那只有右鍵菜單有下載選項。 但我想要的下載過程是這樣的:
因此萌生了自己寫一個擴(kuò)展的想法。
3 結(jié)果
大致可以滿足需求(只考慮一次下載一個的情況),但有一些點暫時不知道怎么解決:
如何在下載未開始前就獲取到下載鏈接(部分文件不支持多次下載)
如何不自動彈出內(nèi)置下載器
新建的窗口如何固定大小/位置,以及如何置頂,如何隱藏標(biāo)題欄(主要是關(guān)閉按鈕)
4 過程
不能科學(xué)上網(wǎng),導(dǎo)致很多文檔看不到,只能側(cè)面摸索。
4.1 參考
文章
chrome extensions
4.2 新建 chrome extension
這部分網(wǎng)上有,下面展示一些自己用到的字段。
關(guān)于權(quán)限部分,「downloads」用來監(jiān)聽下載事件, 「cookies」用來獲取請求鏈接對應(yīng)的 cookie , 「*://*/*」用來獲取 HTTP/HTTPS/WebSocket 鏈接的訪問權(quán)限。
需要注意的是,如果只給了「cookies」權(quán)限,但沒給對應(yīng)的 URL 訪問權(quán)限,也是獲取不到對應(yīng)的 cookie 的。
4.3 獲取重新下載所需要的信息
4.3.1 通用信息
downloadItem
里包含 filename/finalUrl/referrer/fileSize …
注意事項: suggest
一定要執(zhí)行一次,無論同步還是異步,無論是否取消下載。
4.3.2 cookies
4.3.3 組裝 request header
4.4 使用 aria2 下載
到這一步,可以將所有下載鏈接重新用 aria2 下載, sendHttp
部分可從網(wǎng)上找。
4.5 添加提示框
一開始是用「confirm」和「prompt」來實現(xiàn)一個選擇的效果, 但因為有個解決不了的問題:內(nèi)置下載器會自動彈出來。 因此想使用定時器來自動取消下載,但使用「confirm」和「prompt」會中止代碼運行,使得定時器不生效。 假設(shè)在選擇操作前設(shè)置定時器自動取消下載,如果想「suggest」在選擇操作完成之后才運行,那就有可能在等待的過程中, 定時器沒生效,而且 chrome 自己把 「suggest」彈出來了,這時再選擇的話,就會導(dǎo)致「suggest」重復(fù)運行,從而報錯。
由于定時器不生效及操作步驟的原因,考慮實現(xiàn)自定義彈框。
本來想用 JavaScript 實現(xiàn)自定義的「confirm」和「prompt」,不過只找到將控件 顯示/隱藏 的邏輯。 之后想起用到的「沙拉查詞」擴(kuò)展,有快捷鍵顯示查詢面板,粗略看了下,應(yīng)該是使用 chrome extension 中的 content scripts,要在當(dāng)前網(wǎng)頁插入代碼。?感覺略微復(fù)雜,繼續(xù)找,發(fā)現(xiàn) background 能自定義 HTML,但用處不大,因為這個頁面是不顯示的。 之后就找到 chrome.windows.create
,可以創(chuàng)建「popup」窗口,也算能滿足我的需求。
頁面布局和消息通訊就沒什么好講的,網(wǎng)上也能找到。
關(guān)于按鈕點擊事件的要注意一下,因為 chrome extension 不允許將字符串轉(zhuǎn)為可執(zhí)行代碼, 因此要用別的方法實現(xiàn)點擊操作:
還有一個小問題,就是這個彈框的關(guān)閉按鈕不知道怎么隱藏,因此只好加上 window.onbeforeunload
。 如果在 createdCallback
中調(diào)用 chrome.windows.remove
,那也會觸發(fā) window.onbeforeunload
。
5 額外內(nèi)容(JavaScript export/import)
擴(kuò)展可以加一個設(shè)置界面,但感覺不會用到,又想有一個地方配置一些數(shù)據(jù),因此想抽出一個配置文件。 「background」想要引入別的文件的話,要用一個 HTML 以「module」的形式引入 JavaScript。