分清腳本——網頁中的服務器端和客戶端腳本

一般介紹動態網頁開發的資料都會機械式地先講HTML,再則有空講講JS,然後切入正題講動態網頁部分,最後給出一些實例,比如留言板、論壇,甚至小型電子商務網站等等。而更新的ASP.Net甚至可能只從WinForm講起,然後就講WebForm了……這樣更加使程序員無法接觸底層的代碼,無法理解整體架構和工作流程。我認爲ASP.Net的出現有點像高級語言的誕生,高級語言的編譯器實現了自動編譯鏈接高級語言代碼到彙編代碼的過程,雖然最終的代碼未必那麼簡潔,但畢竟經多重優化也在可接受範圍內。而如今的ASP.Net原意想封裝所有的客戶端代碼,實現從WebUI+CodeBehide到HTML的自動生成過程,但由於種種原因現在還做不到完全滿足開發者需要(可以這麼說,它產生的“彙編代碼”不盡如人意),很多基本功能需要了解客戶端腳本,進行手工修改才能實現。 
  正是ASP.Net現在所處的這種矛盾階段,我們更有理由要掌握更多的知識,從HTML、CSS到JScript、behavior、XML。言歸正傳,本文將直接把服務器端腳本和客戶端腳本放在一塊講述比較,這是極少有人做過的,也可以解開一些入門者的困惑,比如爲什麼服務器端腳本就是不能彈出一個對話框、彈出確定框、打開新窗口等等問題。再看看這二者到底管轄和作用了怎樣的範圍,然後再舉例來認識一下如何使這兩個腳本間可以交互,以實現更強的功能。 
 
按此在新窗口打開圖片
圖爲早期PHP4的分層示意,雖然從現在的n層架構來看畫得不甚清楚,但還是能看懂的。兩個腳本很簡單:顧名思義,一個運行在服務器端,一個運行在客戶端。而它們的任務也很明確:服務器端腳本只用於生成網頁代碼(可以包括HTML、CSS、JS等等),它正是平常所說的ASP/ASP.Net、PHP、JSP等等,在動態網頁中一般用“<%%>”、“<??>”等符號包圍,在多層構架中也可以把Beans,CodeBehide等等算進去吧。客戶端腳本就完全是在客戶瀏覽器裏解釋運行的,要麼在“<script>”中,要麼在一些事件裏,要麼單獨一個文件,總之查看源代碼一般都可以看到,對最終瀏覽用戶相對是公開的。它控制着用戶與瀏覽器的交互,如果把瀏覽器看成應用程序,它的所有動作都是客戶端腳本完成的,這就解釋了爲什麼總是沒有彈出對話框的服務器端函數。 
  因爲ASP本身用的腳本與客戶端腳本完全一樣,都是JScript(或JavaScript)和VBScript,所以經常讓初學者感到摸不着頭腦,還有很容易使人混淆的<script runat="Server">這個標誌。其實還是上面說的原則,用“<%%>”包圍起來的代碼肯定是服務器端腳本,當然還有<script runat="Server">裏的(這不都標明瞭是運行在服務器端的嘛),這些代碼經過Web服務器解釋運行後在最後的HTML代碼中肯定是找不到的。還有一點要明白的是,無論是JS還是VBS都可以用來寫任何一端的腳本,只是一般比較習慣用JS來寫客戶端腳本罷了。至於一般用VBS來寫服務器端腳本可能一個是習慣,一個是以示區別。 
  ASP.Net用RegisterClientScriptBlock()、RegisterStartupScript()等方法來在代碼中添加客戶端腳本,以及control.Attributes["event"]="script"來爲控件添加事件處理腳本。懂得這些和一點JScript知識你也許知道如何實現在按個刪除按鈕之前彈出一個確認窗口了,把下面代碼寫在Page_Load裏: 


btnDel.Attributes["onClick"]="return confirm('確定要刪除嗎?');"; 

  但如果你多懂得一點內幕,馬上就會發現這樣雖然能行,但是有很致命的副作用:如果同一頁面中設有validator,儘管validator可以報告有錯誤的輸入,但它們都不能阻止表單提交了!原因在於ASP.Net把你自己寫的那段JScript代碼寫在了按鈕onclick的最前面: 


<input type="submit" name="btnDel" value="Button" οnclick="return confirm('確定要刪除嗎?');if (typeof(Page_ClientValidate) == 'function') Page_ClientValidate(); " language="javascript" id="btnDel" style="……" /> 

  這樣原來的if語句後的那條就無法執行了,而Page_ClientValidate()正是ASP.Net自帶的WebUIValidation.js裏的函數,而一旦影響該函數的正常運行則會使表單不能按原定的方式判斷提交。奇怪的是MS自身提供的範例也有這麼做的。我們稍微更改一下onClick的腳本來獲得正確的做法: 

btnDel.Attributes["onClick"]="if confirm('確定要刪除嗎?') return false;"; 可見客戶端腳本的使用是無處不在的,有時需要熟練的技巧和敏銳的決策,在過去的ASP時代如此,現在的.Net時代亦不外如是。 


# re: 分清腳本——網頁中的服務器端和客戶端腳本(二)2005-01-24 20:19 | 奇思軟件 
或許用我寫的一個組件更方便:) 
此組件從標準button繼承,但在提交之前顯示提示框,依舊支持驗證 

using System; 
using System.Web.UI; 
using System.Web.UI.WebControls; 
using System.ComponentModel; 

namespace Keyss.WebControls 

    [ToolboxData("<{0}:Button runat=server></{0}:Button>")] 
    public class Button : System.Web.UI.WebControls.Button 
    { 
        protected static string _warningScript = "if(!window.confirm('{0}')) return false;"; 


        [Bindable(true),  
        Category("Appearance"),  
        DefaultValue("")]  
        public string WarningMessage 
        { 
            get  
            { 
                object o = ViewState["_warningMessage"]; 
                return o==null?string.Empty:o.ToString(); 
            }
            set  
            { 
                ViewState["_warningMessage"] = value; 
            }
        }
         
        [ 
        Bindable(true), 
        Category("Behavior"), 
        DefaultValue(false) 
        ] 
        public bool EnableWarning 
        { 
            get  
            { 
                object o = ViewState["_enableWarning"]; 
                return o==null?false:(bool)o; 
            }
            set  
            { 
                ViewState["_enableWarning"] = value; 
            }
        }

         
        protected override void OnInit(EventArgs e) 
        { 
            base.OnInit (e); 
            if(this.EnableWarning) 
            { 
                string onClick = this.Attributes["onclick"]; 
                if(onClick == null) 
                { 
                    this.Attributes["onclick"] = string.Format(_warningScript,this.WarningMessage); 
                }
                else
                { 
                    this.Attributes["onclick"] = string.Format(_warningScript,this.WarningMessage) + onClick; 
                }
            }     
        }

    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章