由ASP.NET所謂前臺呼叫後臺、後臺呼叫前臺想到HTTP——實踐篇(一)

謙行發表於2013-09-23

由ASP.NET所謂前臺呼叫後臺、後臺呼叫前臺想到HTTP——理論篇中描述了一下ASP.NET新手的三個問題及相關的HTTP協議內容,發現了為什麼.NET程式設計師會問這些問題而Java程式設計師很少(畢業前及大四實習都是在用Java),為了防止成為口水貼,提前宣告一下,本文不是在說.NET與Java的優劣,糾結於此問題的朋友可能不適合看下面內容

當然不是因為Java程式設計師不用ASP.NET控制元件,我覺得.NET程式設計師很大一部分就輸在.NET平臺尤其是Visual Studio的易用性上了,根本無需瞭解HTTP協議,就可以通過拖拽控制元件做出網頁,也不用瞭解表單提交等最基本知識就可以做到頁面和伺服器通訊,甚至不知道客戶端與伺服器在通訊。

Java就不同了,IDE比較不智慧,沒有拖來拖去的控制元件,甚至Java初學者想寫出“Hello World”都得花上一天時間研究環境變數配置,不瞭解表單和post就取不到input的值,想做網站首先得了解Tomcat等伺服器。沒有什麼便利性可言的Java在強迫我們學習,事情必須明白了,才能做出來,而.NET把這些都封裝好了,拿來就能用,很多在校大學生沒學過Java的話都不知道ASP.NET Web Application怎麼在脫離Visual Studio的情況下執行,更不用說簡單的IIS配置了,根本不知伺服器為何物,被.NET寵壞了。

balabala說了這麼多廢話,意思就是.NET在以其易用性溺愛我們,.NET程式設計師不能一直沉浸在我把XXX給做出來了就很滿足的狀態,而得有一種刨根問底的精神去鑽研其原理,相信已經這麼做的同學在看到網上沸沸揚揚的.NET與Java優劣之爭的時候都會報之於呵呵。言歸正傳,先看看理論篇中最後提煉的幾個問題。

伺服器端如何影響客戶端元素與行為

這個問題通俗講就是,怎麼在伺服器端修改頁面DIV或者“呼叫”JavaScript。如果瞭解了理論篇中的HTTP協議的講解就應該知道伺服器修改頁面DIV或者呼叫JavaScript是不可能的,伺服器只能給瀏覽器一個全新的頁面(不考慮Ajax)。那麼是不是這個問題就無解了呢?確實是!但是,然而可以利用伺服器給瀏覽器全新頁面這一特性來達到好像伺服器修改了客戶端頁面的效果。

來嘗試一下在”伺服器“端修改頁面上的一個DIV為span

<form id="form1" runat="server">
        <div id="test">改我</div>
        <div>
            <asp:Button ID="btnModify" runat="server" Text="Modufy" OnClick="btnModify_Click" />
        </div>
    </form>

對於這種需求一般有兩種思路:

思路一

把需要更改的地方做成伺服器端控制元件,這樣就可以在伺服器端使用規則,把想要的效果修改到全新的HTML文字中,然後傳給瀏覽器,因此可以這樣把頁面改動一下,把欲改動部分用伺服器端控制元件表示

<div id="test">
        <asp:Literal ID="ltrNew" runat="server">改我</asp:Literal></div>
    <div>
        <asp:Button ID="btnModify" runat="server" Text="Modufy" OnClick="btnModify_Click" />
    </div>

這樣就可以在Button的Click事件處理程式中修改DIV中的文字了

protected void btnModify_Click(object sender, EventArgs e)
        {
            ltrNew.Text = "改好了";
        }

看到這裡可能剛入門ASP.NET的同學都要問了:您這是.NET科普嘛?這樣確是比較弱,雖然常用但很多和頁面互動的地方需要JavaScript來處理,並不是簡單的改變文字就可以做到的,這時候就要換換思路了

思路二

本來應該客戶端做的事情就應該讓客戶端來做。拿上面的例子,可能頁面上已經有JavaScript方法來處理修改DIV內文字了,欠的就是伺服器端呼叫了。

function modifyDivLiteral(newliteral) {
            //..............
            //一系列不是伺服器改文字能處理的操作,比如建立新的Array、改變Div背景顏色,呼叫其他JavaScript函式
            //............
            document.getElementById('test').innerHTML = newliteral;
        }

你看這個函式要做的事情相當複雜,沒發通過伺服器改文字做出來,怎麼辦!貌似伺服器呼叫JavaScript方法是個不錯的路子,但前面的理論已經告訴了我們不可能,伺服器給瀏覽器的時一個新的HTML文字,又不是呼叫函式的控制程式碼,但是如果我們往新的HTML頁面裡新增的呼叫此方法的語句不就實現了嗎?來看看我們怎麼實現向新的HTML文字中新增呼叫JavaScript的語句。

先在頁面上新增一個literal控制元件用來存放新追加的呼叫JavaScript函式語句,至於放在最後是因為執行此語句的時候我們需要頁面上的元素已經準備好,當然也可以通過jQuery的ready實現

<form id="form1" runat="server">
    <div id="test">
        改我</div>
    <div>
        <asp:Button ID="btnModify" runat="server" Text="Modufy" OnClick="btnModify_Click" />
    </div>
    </form>
    <script type="text/javascript">
        function modifyDivLiteral(newliteral) {
            //..............
            //一系列不是伺服器改文字能處理的操作,比如建立新的Array、改變Div背景顏色,呼叫其他JavaScript函式
            //............
            document.getElementById('test').innerHTML = newliteral;
        }
    </script>
    <script type="text/javascript">
        <asp:Literal ID="ltrScript" runat="server"></asp:Literal>
    </script>

這時候事情就簡單了,可以像剛才那樣修改文字一樣修改Literal內容,區別只是我們需要新增的文字是JavaScript語句

protected void btnModify_Click(object sender, EventArgs e)
        {
            this.ltrScript.Text = "modifyDivLiteral('改好了');";
        }

這樣點選按鈕後效果是這樣的,可以看到Literal部分已經變成了呼叫函式的語句,這樣DIV內容就被修改了,我們就從效果上實現的伺服器“呼叫”JavaScript

image       image

思路二加強版

效果是有了可是這樣寫好醜陋啊,又得自己加個Literal,搞笑的是還得使用一對script標籤包起來。

確實是,其實還有其他方法,比如呼叫Response.Write、Page.Controls.Append啊等等,大同小異,這樣寫最容易理解,一旦我們知道為什麼這樣就可以讓伺服器“呼叫”JavaScript後,就可以用.NET貼心的方法來做此事了,.NET團隊已經想到了開發者會有這樣的需求,特意設計了幾個內建函式解決伺服器端向頁面註冊指令碼的問題。

Page.ClientScript.RegisterClientScriptBlock

把指令碼註冊到頁面頂部

Page.ClientScript.RegisterStartupScript

把指令碼註冊到頁面底部

Page.ClientScript.RegisterClientScriptInclude

向頁面註冊指令碼檔案

關於這Sanger方法具體解釋及用法可以去網上搜一下資料,前兩個的區別是把指令碼註冊到頁面的什麼位置,第三個可以把一個指令碼檔案引入頁面,這個例子中應該使用Page.ClientScript.RegisterStartupScript,這時候醜陋的包裝就可以刪去了

<script type="text/javascript">
        <asp:Literal ID="ltrScript" runat="server"></asp:Literal>
    </script>

正想截圖呢,發現犯了一個錯誤,這個方法把指令碼註冊到form的底端,而不是body,所以頁面也要稍微修改一下,把modifyDivLiteral方法往前放一放

<form id="form1" runat="server">
    <div id="test">
        改我</div>
    <div>
        <asp:Button ID="btnModify" runat="server" Text="Modufy" OnClick="btnModify_Click" />
    </div>
     <script type="text/javascript">
         function modifyDivLiteral(newliteral) {
             //..............
             //一系列不是伺服器改文字能處理的操作,比如建立新的Array、改變Div背景顏色,呼叫其他JavaScript函式
             //............
             document.getElementById('test').innerHTML = newliteral;
         }
    </script>
    </form>

這樣最後生成的頁面是這樣的,是不是達到預期目的了呢

image

未完待續

總而言之,由於瀏覽器並不是把頁面全文發給伺服器,也就是說頁面上的DIV及JavaScript語句並沒有傳送到伺服器,在伺服器端想修改DIV或者呼叫JavaScript是不可能的,要麼修改頁面原始碼,讓瀏覽器載入新的內容,達到更新目的,要麼就像預約,或者點菜,向頁面注入指令,讓頁面在瀏覽器端做某事。

本來想一篇說完呢,沒想到最簡單的問題內容就這麼多,只好分篇說了,欲知客戶端如何”呼叫“伺服器端方法,且聽下回分解

相關文章