星期三, 七月 28, 2010

動態新增、修改、刪除 CSS Rule

需求:有一個動態網頁,每個物件都是動態載入,每一種物件都允許自訂顏色,因此我用物件的type id做為CSS的名稱,設定後立即生效。
利用jQuery搭配AJAX確實很方便,但是jQuery的selector只針對目前存在的DOM物件有效,雖然有神奇的 .live ,很可惜只對Event有效果,對於CSS並沒有類似的API。
後來找到JavaScript Kit上的Changing external style sheets using the DOM,照著這三篇的做法就可以動態新增、修改、刪除 CSS Rule,不需要在檔案定義。黑暗執行緒李明儒大師寫了篇動態加入預設Style設定,將新增預設CSS Rule擴充至jQuery。我自己先簡單地把修改的部份直接寫成先檢查存不存在,若存在就刪除再新增,這樣很不好的暴力寫法XD 程式碼如下:
function changeCSSRule(classToSet, rulesToSet) {
    for (var k = 0; k < document.styleSheets.length; k++) {
        var mysheet = document.styleSheets[k];
        var myrules = mysheet.cssRules ? mysheet.cssRules : mysheet.rules;
        mysheet.crossdelete = mysheet.deleteRule ? mysheet.deleteRule : mysheet.removeRule;
        for (var j = 0; j < myrules.length; j++) {
            if (myrules[j].selectorText.toLowerCase().indexOf(classToSet) != -1) {
                mysheet.crossdelete(j)
                j-- //decrement i by 1, since deleting a rule collapses the array by 1
            }
        }
        if (mysheet.insertRule) {
            mysheet.insertRule(classToSet + "{" + rulesToSet + "}", 0);
        }
        else if (mysheet.addRule) {
            mysheet.addRule(classToSet, rulesToSet);
        }
    }
}
比較弔詭的情形是若只改document.styleSheets[0]的話是無效的,所以我昨天照著這裏的範例試並沒有成功,各位朋友可自行測試。

MSDN上addRule有許多限制,在IE7及以下並不支援selector或是"b, a"這種同時設定兩個以上class的寫法,但支援"div a"之類的寫法,請注意。

星期三, 六月 30, 2010

大家都做的事並不一定是對的

剛才MIS小姐的程式出現一個奇怪的Bug,在IE可以正常執行但是在Chrome完全沒有反應。我看了一下發現她用AJAX load一個完整的html進來塞在div裏,她認為這樣在第一頁有載入 jQuery,在這頁就不用再載入。

她在別人的網頁看到這種做法,但是大家都做的事並不一定是對的
首先,html、head、body都是只允許出現一次的tag,所以正確的做法應該是在div裏做個iframe再指向html。若想要做成網頁的一部份,就應該只load進部份的html內容而不能包含html、body等tag。
其次,因為是不標準的做法,所以各家瀏覽器對這種情況的處理就不一致,不能怪Chrome認為jQuery不存在。目前雖然可以在動態載入頁面載入jQuery的script tag暫時解決,不代表這種做法是對的,未來的版本仍可能會改變此行為。

Update:向神人朱大師請教後,才知道我只看到結果,但推論是錯的!
大師說:
jQuery 用 ajax load html 時,會自動把 html, body 濾掉;載入時 HTML 還是全部會載進來,然後 jQuery 才會用 dom 的方式去濾掉,所以在濾之前的 dom 載入動作,就要看各家瀏覽器怎麼實作。
保險的方式,是請小姐把 script 標籤移到</body> 之前,各家瀏覽器對 JavaScript 語法的容錯程度不一,還是標準一點好

今天這件事就像很多人都有陽台外推,在頂樓搭違建或占用家門口的馬路當車位一樣,雖然大家都這麼做,不代表你可以這麼做,未來可能也不允許這麼幹呀!

星期二, 六月 29, 2010

關於架站機的兩三事

2006年由於 蔡依林的部落格 一文意外讓廖大紅了,沒想到今天發表的總統府新網站也讓T客邦發表一篇介紹文

因為在下對敝公司的網站非常不滿意,所以之前評估過非常多的架站機,後來又因開發某專案的緣故,所以也對.Net的架站程式做過測試。
其實大家都在用架站機,重灌狂人、藍藍路等人也用Wordpress或Xoops、Drupal、Joomla等架站軟體,以方便維護。那問題出在哪兒呢?在價格。蔡依林的部落格號稱花500萬,實際上那種品質應該50萬都不到,但是總統府網站卻真的花了700萬去發包,所以被高手們用放大鏡檢視。700萬其實也不會有多好賺,公家機關的估價應該有一半是設備費,外加3年維護及保固;不過案子夠大,利潤保守估計也有100萬以上。(我真的很保守了)

先說一下這次的主角DotNetNuke好了,它是用Visual Basic所開發出來,最早是以微軟放出來的範例程式為藍本改寫出來的架站機,後來因為廣受好評,以功能上來說算是.Net架站機的翹楚,相當於Xoops在PHP架站機的地位,但問題也與Xoops相同。

早期的DotNetNuke有個令人討厭的缺點以至於敝公司開發專案不願意使用它,不是因為它用VB.Net不是C#,而是那時連到menu裏的每個項目都用名稱而不是id(正確地叫tabid)去連結,因此我們這種早期web開發者看到中文URL就吐血,決定放棄。當然還有這次本次令人髮指的XSS問題,這種架構性的缺點很難修改。

敝公司的網站用哪一套架站機呢?是一套商用軟體,所以並不多加介紹,但必須說明它是PHP+MySQL的架構。在我們買的當時以相同的硬體,執行LAMP與DotNetNuke比起來,速度真是天壤之別,只是要讓內容維護者使用而不自行加值,當然選擇後台功能強的架站機。那個廠商說他們有一套賣給種花電信某單位,由於流量很大,還客製化成為後台直接產生靜態頁面發布,在下覺得他們確實很了解狀況。

敝公司自己開發的專案使用Rainbow Portal,當時的選擇不夠多,事實也證明Rainbow Portal有點慢,但是開發模組很方便,也就硬著頭皮把案子做完,後來2005年之後它幾乎沒有再維護,所以在後續的案子也就不使用。用DotNetNuke開發總統府網站,就必須小心地檢視它的先天性弱點,由於DotNetNuke是Open Source,絕對會有不少人找出它的弱點來攻擊,開發廠商皮得繃緊點了。

目前的架站機或多或少都無法令所有的使用者滿意,最主要的問題還是在於後台管理不夠方便,好用的架站機都是商用程式,我想這也是商業化的價值。

如果現在要我選個內部使用的架站機,我應該會選Drupal或Joomla,但若要安全又快速也不考慮維護性的話,自己拉幾個網頁最快啦~

星期四, 六月 24, 2010

使用PHP 4.1.2+Apache 1.3.42+mod_ssl

敝公司幾年前買了套很舊的架站機,它用Zend 編碼PHP,因此只能用PHP 4.1.2+Apache 1.3.X,我只能默默的更新。

這兩天開始會神奇的無回應,檢查error_log發現是達到MaxClients,看了access_log似乎是Sogou web spider有些問題,而我也不想去擋偉大的祖國蜘蛛(誰知道還會有哪隻呢?),所以檢查httpd.conf,發現TimeOut居然被設成1800(秒),原本預設值是300,所以我改成100,這樣httpd的數量就維持在50左右。

因為每天都有不少試漏洞的robots,所以更新是必要的,在此記錄如何編譯Apache 1.3+PHP 4.1.2+mod_ssl

星期五, 六月 18, 2010

RT2870/RT3070在Linux的driver

由於舊的無線網卡故障,原本向朋友借了一支他不用的802.11b usb網卡;但實在收訊太差速度又慢,於是忍不住買了張便宜的EDIMAX EW-7711UMn USB無線網卡。由於什麼都不奇怪的網站上寫明支援Linux/Mac,所以才放心買下。
但是拿到手後在Windows沒問題,在Ubuntu和Mac使用內建的driver都抓不到,裏頭附的光碟有Linux及Mac的driver,但Linux版編譯不過,又到雷凌下載最新的driver,晶片組應該是RT3070,裏頭的Makefile有點小問題,而且修改安裝後仍然抓不到。

後來看到這篇才知道要disable RT2800 的module,仔細找找原來在Ubuntu 10.04已經內建 RT2800及更新版晶片的driver,所以不用像這位大哥或在下這麼費工,還不一定會成功。

重點:在 "/etc/modprobe.d/blacklist.conf" 加上 blacklist rt2800usb 就夠了。

還沒完咧,重開機後果然抓到driver,但是很怪異連不上WPA+WPA2 personal的新Wireless AP,只能連到WEP的舊AP,再google搜尋一下,發現這是Linux rt2800 driver的Bug,支援WPA2但不支援WPA,所以把AP設成WPA2 only就可以連線。

結論:Linux愈來愈好用,但因為driver的不完善,不想浪費時間的朋友還是選擇Mac/Windows比較方便;我想RT2870的問題在Ubuntu 10.10說不定就會解決,所以我還是會繼續用下去 ^_^

星期二, 六月 15, 2010

神奇的Mac OS X

先聲明,我不是瘋狂的Apple Fans,也不是反微軟教派,但是這次真的讓我對OS X佩服得五體投地。

午休結束後,負責維修的同仁向主管報告遇到某幾個pdf印不出來,於是乎主管又叫我幫忙處理。一問之下,這幾個檔案是某政府單位做的pdf,乍看之下是用PowerPoint 2007直接另存成的,裏頭有90%都是精美的圖...(誰要去政府機關教高橋流簡報呀?花到不行的簡報誰知道重點在哪?)圖多並不是問題,這幾個檔最大的也不過五十幾Mega Bytes,還不到60頁;但真正的問題在於每印一頁都慢到不行,而且印到一半Adobe Reader就會當掉卡住,另存或是用Adobe Acrobat去修也沒用。

由於當時距離大老闆要的期限只剩2小時,我就不加思索拿出我的Macbook Pro,打開一試...有點慢,但是可以另存,表示可以印!於是用我的Mac印到Windows分享的印表機,但由於印表機太慢,要連別台印表機同步列印時居然因為機型太舊找不到Snow Leopard的driver!

當時我的確傻眼,沒想到台灣Xerox租借的DocuCentre-II 3005居然是過時的產品,沒有出新版Mac driver;後來看到官網寫可以用PS相容模式列印,於是用Generic postscript driver,就直接丟到DocuCentre-II 3005印出檔案,問題也就解決。

在下猜想,那幾個pdf檔不知是什麼原因造成格式錯誤,剛好Adobe使用的API會卡住(我用Foxit Reader測過,也印不出來);但Mac OS X的Preview(預覽程式) 就是沒問題,只能說好樣的Mac OS X,你真神!

Update:因為許多朋友猜測是driver等問題,後來又以Ubuntu 10.04測試,結果仍然是Adobe Reader在列印時會當掉,用xpdf則有破碎字問題且亦無法列印。後來發現那幾個pdf檔是以"DocuCom PDF Driver 6.03 for NT"製作,應是該轉檔程式之bug。

星期五, 六月 11, 2010

Visual Studio Express 切換語言

如同大家所知,下載 Visual Studio 2010 Express的中英文版並且都安裝後,就可以切換介面顯示的語言(語系),但我卻找不到 =.=

原來是從Visual Studio Express和要錢的Visual Studio不同,預設不會顯示所有的設定,必須要勾選 "顯示所有設定" 才能在 "環境"->"國際設定" 的 "語言" 裏去修改。



改完這裏後,在方案總管裏,right click aspx也出現 "瀏覽方式..." 的選項,就不用擔心更改預設瀏覽器而不能直接啟動 IE debug。

比沒錢又贏了

午休時和朋友msn聊天,再一次的又沒人能贏我。以下採用藍藍路的msn式對話:

=============================================
接受 說 (下午 01:00):
我想買Wii但是我身上前好少
[鳥毅] 說 (下午 01:01):
 你錢少?
 有沒有搞錯
接受 說 (下午 01:01):
 對阿
[鳥毅] 說 (下午 01:01):
工作十年,我戶頭剩不到60萬
接受 說 (下午 01:01):
 什麼
[鳥毅] 說 (下午 01:01):
 也沒股票等不動產
接受 說 (下午 01:01):
 好吧 我輸了
[鳥毅] 說 (下午 01:01):
 嗯,知道就好,哈
接受 說 (下午 01:01):
 哈
=====================================================

改版型了

其實早就想改版型,但因為沒有好的工具一直懶得改。

上個月被Google AD停權就一肚子鳥氣,今天剛好遇到Blogger提供Template工具,就直接按套用,也不放廣告了。

星期三, 六月 02, 2010

WinForm裏ToolBar/ToolStrip不會先Focus的Bug

同事遇到一個奇怪的Bug,她說用DateTimePicker手動改變時間,在儲存時卻不會生效。原本我以為是DateTimePicker的Bug,仔細一查卻發現是她用的ToolBar的Bug,這情形在較新的ToolStrip元件也會發生。

因為在下很久沒有寫WinForm,所以昨天特地下載Visual C# 2010 Express測試。先拉一個DateTimePicker元件、ButtonToolStrip元件,接著在ToolStrip增加一個Button,雙擊之,再加入兩行。

MessageBox.Show(dateTimePicker1.Text);
MessageBox.Show(dateTimePicker1.Text);

執行後去改dateTimePicker1的值,在日期仍反日時馬上按toolStripButton1,會發現第一次是今天的值,第二次才會更新;但若用button1則不會有這問題。

因此解決就是在toolStripButton1_Click() 加上
toolStrip1.Focus();
此處Focus在dateTimePicker1以外任何其他元件均可。
完整測試程式如下:
using System;
using System.Windows.Forms;

namespace TestDateTimePicker
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void MessageTwice()
        {
            MessageBox.Show(dateTimePicker1.Text);
            MessageBox.Show(dateTimePicker1.Text);
        }

        private void toolStripButton1_Click(object sender, EventArgs e)
        {
            toolStrip1.Focus();
            MessageTwice();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            MessageTwice();
        }
    }
}

執行畫面如下:

星期二, 六月 01, 2010

硬碟的容量,決定宅的力量

俗話說:『硬碟的容量,決定宅的力量』,最近 "影片"存量 VM過大,所以在下敝人小弟我就去買了一顆最便宜的eSATA外接式 1.5 TB 硬碟;這樣在公司的電腦裝Ubuntu也不會有罪惡感。
聽說有了這顆硬碟後,VM帶回家就可以繼續工作!(啥?是把和同事交換的謎片帶回家吧?)
因為也有USB,如果想要拿來當MacBook Pro的Time Machine也可以;不要亂搞的話,裝3~4個OS多重開機加上資料可攜是沒問題的。

差點忘了提價格,我在什麼都不奇怪的購物中心買,隔天早上送到花了NTD $4299,聽說有賣NTD$3999,懶得去找了。送到才發現沒有附eSATA的線,所以安裝Ubuntu得等我再去買eSATA線,下回待續...

星期五, 五月 14, 2010

jQuery UI Datepicker繁體中文年月選單換行的小修正

jQuery UI 1.8.1的Datepicker如果設定為繁體中文(localize calendar) 並同時啟用顯示年月選單(Display month & year menus)時, 會變成:
解決方法很簡單,用編輯器打開 e:\TEMP\jqueryui\development-bundle\themes\[theme name] 底下的 jquery.ui.datepicker.css 或 jquery-ui-1.8.1.custom.css ,找到 .ui-datepicker .ui-datepicker-title 的 class,加上 white-space: nowrap; 存檔修正後:

星期四, 五月 13, 2010

升級到Ubuntu 10.04

最近在趕一個程式,所以這篇拖到今天才寫。

上星期一邊趕程式一邊打開Ubuntu桌機,把9.10升級到10.04,結果裝好重開機後出現以下畫面:


原本還以為是driver出問題,但我用PrintScreen抓下畫面也如此,就知道是別的東西造成。登出後用 "Gnome安全模式" 登入就正常,再檢查 "系統"->"偏好設定"->"始動應用程式"(記得以前叫啟動應用程式?),把"NVIDIA X Server Settings" 設為不啟動就好。因為現在使用內建顯示卡而不是Nvidia顯示卡,才發生這種鳥事。前一版的NVIDIA設定程式並沒有這個問題,雖然是Bug但不要亂裝程式的朋友也不會有問題。

這件事告訴我們:不要妄下斷言。如果我跑到論壇去求救或罵Ubuntu不就糗大了? ^_^

星期三, 五月 12, 2010

重新學習JavaScript

因為1997年看過一點第一代的JavaScript,到2000年時就大幅度改寫,於是我一直很討厭學JavaScript。

最近因為被主管要求寫一個具有AJAX效果的網頁,所以再拿出jQuery in Action來看,書沒看完就寫code果然犯了兩個嚴重錯誤。

第一個錯誤就是因為bind事件因closure造成的memory leak。。在jQuery in Action的附錄有寫closure和memory leak,在 重新介紹JavaScript裏也有寫以下範例:
function addHandler() {
    var el = document.getElementById('el');
    el.onclick = function() {
        this.style.backgroundColor = 'red';
    }
}
要加上e1=null; 才不會memory leak
function addHandler() {
    var el = document.getElementById('el');
    el.onclick = function() {
        this.style.backgroundColor = 'red';
    }
    e1 = null;
}
第二個錯誤則是知道memory leak後在所有function底下把變數加上 xxx=null的宣告。這樣有什麼問題呢?一般的function不會有什麼問題,但我用了jQuery的$.ajax,非同步的宣告使得success的function比較晚執行,傳進去的closure變數已經被清空,所以原本可以執行的程式又變成不能執行。若要釋放變數應該要放在success區段的最底下。
function fail2() {
   var param = $("#somewhere").val();
   $.ajax({
        url: "test.php",
       dataType: "text",
       success: function(ret) {
          // 以下用到 closure的變數 param
         var xyz=param+ret; 
         // do something
       }
   });
   param = null; //在這裏釋放就錯了
}
要改成
function fail2() {
   var param = $("#somewhere").val();
   $.ajax({
        url: "test.php",
       dataType: "text",
       success: function(ret) {
          // 以下用到 closure的變數 param
         var xyz=param+ret; 
          // do something
         param = null; //在這裏釋放才對
       }
   });
}
只能說當掉重修呀.... Orz

星期六, 五月 08, 2010

行銷

韓國人真的了不起,行銷功力一流,去年利用YouTube捧紅了Wonder Girls和Super Junior,現在又有Applegirl利用YouTube自己行銷,聽說已經有唱片公司簽約。
尤其利用3支iPhone演奏,實力頗強



星期五, 四月 16, 2010

胡歌 online

甲女和乙女是好朋友,前幾年常一起打線上遊戲,近一年來都很少玩,某天乙女到甲女家中做客。

乙女問甲女:妳最近都在玩什麼?聽妳兒子說妳整天都霸著電腦不放,害他都不能玩。
甲女:沒有啦~ (羞澀貌)

此時甲女的在老公忽然冷不防地冒出一句:胡歌online啦!

乙女一頭霧水,原來是甲女看了胡歌演的神話電視劇之後,每天上網看胡歌的連續劇,哈!

星期四, 四月 01, 2010

OSX PPTP VPN Connects but doesn't work

I met the problem: Mac VPN PPTP Connects but doesn't work. Even if I modified routing table, still doesn't work.

遇到如Mac VPN PPTP Connects but doesn't work相同的情形,Mac撥號pptp server成功,但怎麼樣都ping不到,明顯是不知哪個環節錯了,手動改routing table也沒用。

I backup and erase the contents of /Library/Preferences/SystemConfiguration, then after a restart I have to reset network and VPN worked again.

我照討論區裏將 /Library/Preferences/SystemConfiguration 裏的檔案備份並刪除,重開之後重新設定網路,VPN就正常運作。

But you have to notice, remove these configuration files will influence many thins.
必須要注意刪除這些設定檔將會影響許多東西,請小心。

Update: 據強者表示,刪/Library/Preferences/SystemConfiguration下的com.apple.airport.preferences.plist、com.apple.nat.plist、com.apple.network.identification.plist就夠了,需要的朋友可以試看看。

星期三, 三月 31, 2010

基礎建設的差距

前陣子到台北縣3G上網就覺得很慢,被人說NPNT,所以昨天經過特地記錄一下,基礎建設的差距實在太大了呀!
第一次測試實在慢到爆,這是在永和四海豆漿附近的大馬路上

第二次測是是同一地點,數據好一點了,但網路快快慢慢,不是很穩


最後這是今天早上在台北市南京東路上,比用ADSL上網還快

星期一, 三月 15, 2010

設定Static ARP

最近ARP病毒又再度流行,由於某個奇妙的暗黑原因,敝公司只有broadcast網段,熟TCP/IP架構的朋友,看到這就知道在下被搞得多慘,沒有切割網段,遇到fake arp就只能含淚接受,要死大家一起死。

由於長官不肯花錢愛地球環保不換網路設備,也無法設定VLAN,只好用靜態ARP的方式減少問題。

在Linux/FreeBSD設定Static ARP,最方便的方法就是設在 /etc/ethers ,開機時會自動匯入,設好後可以下指令 arp -f 或arp -f /etc/ethers 立即生效。

/etc/ethers 可以用 Ethernet‐address配合FQHN或IP Address,格式如下:
08:00:20:00:61:CA pal
08:00:20:00:61:CA 168.95.1.1
但是不知為何,手上的FreeBSD 8接受的格式和MAN pages裏寫的不同,先寫FQHN/IP Address再寫Ethernet‐address
168.95.1.1 08:00:20:00:61:CA

在Windows設定靜態ARP,寫個批次檔或下指令
arp -s 157.55.85.212 00-aa-00-62-c6-09

請注意Windows接受的Mac Address/Ethernet Address是以"-"分隔,un*x是以":"分隔

FortiGate無法靠介面設定,必須連到console設定
config system arp-table
edit 3
set interface port2
set ip 172.20.120.161
set mac 00:09:0f:69:00:7c
end
名詞解譯
FQHN: fully‐qualified‐host‐name ,也可以使用 /etc/hosts裏的hostname
Ethernet‐address: An ethernet address is expressed in ASCII form as "x:x:x:x:x:x"

參考資料:
了解ARP病毒
FortiGate OS CLI Reference

星期三, 三月 10, 2010

Mac通訊錄無法與Google Contacts同步生日

同事說他的Google Contacts無法與Mac同步生日欄位,才發現Mac的通訊錄居然預設沒有生日欄位。透過iPod Touch/iPhone同步之後,Mac通訊錄在有生日資料的通訊人會出現生日欄位,但在Google Contacts仍然不會更新,反之亦然。

參考資料:
Google:Contact won't sync if it includes a birthday or anniversary
Google Contact Sync 說明
Apple: Sync contact with google contacts birthday not syncingSync contact with google contacts birthday not syncing

目前應該是無解,看Apple什麼時候要改同步程式(或者和Google商量加欄位)吧 >_<