學著做 Widget

這兩天照著 NKtalk 上面所提供的〈Kijiji 台灣 Dashboard Widget〉,結果還真的給我改出了一個東西:教育部國語辭典 Dashboard Widget(下載),算是寫出了一個似乎有用的 Widget。

教育部國語辭典

因為是抄來的,所以長像實在是差不多,基本功能與原理也很類似:同樣是使用 JavaScript 的 XMLHttpRequest,從某個網站抓取資料,然後繼續用 JavaScript 來 parse 字串,將處理過的內容更新到頁面上的某個 div 上。原理是這樣,但是實際處理起來其實相當麻煩,雖然說抄來的程式碼可以用,但是其實是有看沒有懂,因為之前從來沒有過使用 Javascript 來 parse 字串的經驗(一般來說,如果是在寫各種網頁服務的話,這種事情通常在 server 端就做好了,不會在 client 端做),而用其他語言三兩下可以寫出來的程式,用 Javascript 所寫出來的結果卻像是天書一樣又亂又長。

而,雖然說在 Dashboard 裡頭的 widget 不過就是個網頁,但是所有的網頁寫得都實在非常奇怪,比方說,在可以看到的幾個範例中,都是先用 img 語法先放一張圖片,然後再放上給個 div,以絕對定位的方式放置選單以及圖文內容…這麼寫的原因是,因為 Dashboard 的背景不同於一般在瀏覽器中所開啟的網頁,一般網頁通常是讓背景填滿,但是 widget 則不然,多是以單一圖形作為背景,而不是將背景填滿,而在啟動某個 widget 的時候,系統會先顯示一張圖片(Default.png)代替。因為這些差別,所以寫出來的 HTML 雖然不至於看不懂,但是實在讓人不習慣。

而我在學著寫 Widget 的時候,同樣遇到 NKTalk 上面所提到的一個惱人的問題,是這樣的:

這個問題主要是因為 AppleWebKit 的 XMLHttpRequest 在讀入某些網頁資料時,其編碼並不會正確轉換成 UTF-8(Unicode),把非羅馬語系的資料硬解議成 ISO-8859-1(羅馬語系)的文字所致。解決方法是利用 AOK’s JavaScript Library 所提供的 _from_utf8 函式將 AppleWebKit 轉錯的內碼再轉成對的 Unicode。但缺點是轉換過程比較慢,且有 0.1% 的錯誤率,不過這是目前唯一可以解決此問題的結法。

狀況似乎是這樣的,在 XMLHttpRequest 試圖開啟某個網頁的時候,如果這個網頁並沒有標記關於編碼的 metadata,就會預設以 ISO-8859-1 編碼開啟,造成非歐美語文的頁面變成亂碼,如果在網頁上加上相關的資料,就我的經驗是可以解決問題。不過,這又牽涉到必須能夠修改在 server 端上的網頁。

所以,或許比較簡單開發 widget 的方式,就是另外弄一台 server ,把該做的事情都在 server 端做好,最後再輸出成乾淨簡潔的網頁讓 widget 讀取,例如, OIKOS 的 widget 就是抓 http://www.oikos.com.tw/v4/newswidget.php這一頁的資料,而我自己也依樣畫葫蘆抄了一個 widget (下載),很奇怪的,我的 widget 在抓取 http://zonble.net/wp-widget.php 的資料時,需要設定編碼 metadata 才能夠正確顯示,OIKOS 卻不用,怪哉!

說到 widget,今天突然發現作業系統內建的氣象 widget 居然無法抓取台北的天氣資料,有人說,因為這個 widget 抓的是氣象網站 AccuWeather 的資料,而 AccuWeather 最近改了站上的資料,「Taiwan」在亞洲國家列表中消失,AccuWeather 不再提供「Taipei, Taiwan」的天氣,而必須改用「Taibei, China」,才能顯示,而且天氣資料很不準。

可是剛剛「Taipei, Taiwan」又可以了,完全搞不懂是怎樣一個狀況。

3 thoughts on “學著做 Widget

  1. 恭喜恭喜,Mac 界有福了!有 zonble 兄這樣的高手加入 Dashboard Widget 設計,相信一定會有更多更有用的 widget 加入,請繼續努力!

    關於 AppleWebKit JavaScript 的 XMLHttpRequest“猜錯”沒有 meta data 提示的編碼,老實說,現在還沒有抓出規則,不過這是一個已知的 bug(國外已經有人 file 這個 bug 給 Apple 了),希望之後他們可以修掉這個 bug。

  2. zonble與nk兄:
    其實我是在php最前面產生三個字元:EF BB BF
    後面的字就可以被辨認為 UTF-8 了。

Comments are closed.