利用 AutoHotKey 達成 IE Javascript Inject

最近在進行的一個計劃,其中一個關鍵步驟是要在另一個網頁上插入額外的功能,但這個網頁的 code 是我碰不到的東西,於是就要找一些方法來把需要運行的 script inject 進去。

GreaseMonkey

最開始想到的是透過 GreaseMonkey,可以在網頁開啟後自動修改其內容,但在 IE 裡,幾個 plugin: IE7Pro(官網已燒燬), Trixie, gm4ie (根本沒官網) 看起來都停止開發了,到底跑不跑得起來也還是個問題,況且還要額外安裝看似 bulky 的 plugin,嗯~不那麼喜歡。

Bookmarklet

另一個方式是有點像新同文堂所提供的 Bookmarklet,在我的最愛列裡面擺一個網頁捷徑,內容是想要插入的 javascript,以外部按鈕的方式提供控制網頁內容的功能。

這的確是個可行的方式,也不失其方便性,在 Chrome 的開發環境中也可以正常的運行,但一轉回到 IE,就悲劇了。

因為要控制的那個網頁裡設定了 window.onbeforeunload 事件,它可以好心的在離開網頁之前提供一個重複確認的機制,避免誤觸關閉或連結而離開。不過這個事件在 Chrome 裡如果直接使用是沒有作用的(得透過 jQuery bind event),但是在 IE 裡,不論是關閉視窗,點選連結,甚至連結的內容只是一段 javascript 都會被觸發。

另一個問題在於,按下確定離開後,該網頁會啓動一些 script,清除一些變數、外掛程式等等,雖然我的 Bookmarklet 不會真的關閉網頁,而且也可以執行,但畢竟有一些系統原有的功能被影響到,而且每執行一次 Bookmarklet 都要多按確定一次,用起來還是不理想。

對網頁裡的 a 標籤來說,解法是透過 onclick 事件來取代 href 內容,但如果是 Bookmarklet 形式的連結,卻是沒辦法設定 onclick 事件的。

自己寫 Plugin (握拳)

有沒有可能自己寫一個 IE Add-on,來做這個事情呢?即使扣除掉我對 M$ 程式開發根本不熟,再加上搜尋到的 platform (Add-in Express, Kango) 都是要收費的,耗費的總體成本實在太高,我做的東西又不是要拿來賣錢的,這個投資相當不划算。

AutoHotKey (AHK)

前一陣子體驗到用 AutoHotKey 來控制網頁物件後,靈光一閃,應該也可以新增一個 script element,然後把要執行的 code inject 進去吧!後來發現,用 document.createElement() 實在是太過迂迴,乾脆直接用 window.execScript() 來執行。

; set hotkey: Ctrl + 8 to trigger javascript injection
$^8::
  ; get IE obj.
  ; IEGet() is available at http://www.autohotkey.com/board/topic/64563-basic-ahk-v11-com-tutorial-for-webpages/
  wb := IEGet()

  ; the script for injection
  myL =
  (
    alert("test JS inject in IE by AutoHotKey.");
  )

  window := wb.document.parentWindow
  window.execScript(myL)
Return

以上 script 運作原理:先用 Basic Ahk v1.1+ COM Tutorial for Webpages 提供的 IEGet() 來取的目前 IE 物件,接著用 document.parentWindow 取得 window 物件後,即可使用 window.execScript() 來執行 script。

上面的 demo 或許不夠理想,畢竟如果只是要做到 alert() 的效果,AHK 本身就有 MsgBox 的函數可以用,不過這只是要 demo: 「可以用快速鍵的方式成功的在網頁裡執行一段外加的 js code」。

雖說透過 AHK 一樣得額外安裝軟體,但基於平常就有搭配 AHK 在使用的習慣,相對來說是比較不會增加額外的負擔的。

突破這個癥結點後,原先的計劃就可以繼續下去啦!已經停擺超久的了。再不開工就要開天窗了!XD