由ASP.NET所謂前台調用后台、后台調用前台想到HTTP——理論篇


工作兩年多了,我會經常嘗試給公司小伙伴兒們解決一些問題,幾個月下來我發現初入公司的小朋友最愛問的問題就三個

1. 我想前台調用后台的XXX方法怎么弄啊?

2. 我想后台調用前台的XXX JavaScript方法怎么弄啊?

3. 怎么用JavaScript找到/創建/修改XXX這個服務器端控件啊?

每次我會跟小朋友分析一下為什么會有如此荒誕不經的想法,然后說原來你做XXX啊,那你應該這樣,可發現這種模式太失敗了,因為隔幾天我又會聽到小朋友還是有類似的疑惑。

我決定以后再有誰問這個問題,我就讓誰給我講講HTTP協議,幾次過后效果非凡啊,看看這兩個問題和HTTP協議有什么關系吧

HTTP協議

HTTP協議即超文本傳輸協議 (HTTP-Hypertext transfer protocol) 是分布式,協作式,超媒體系統應用之間的通信協議。是萬維網(world wide web)交換信息的基礎。是一種詳細規定了瀏覽器和萬維網服務器之間互相通信的規則,通過因特網傳送萬維網文檔的數據傳送協議。

這是從百度上抄來的定義,感覺味同嚼蠟,反正我要是問人什么是HTTP,要是這么回答我,我肯定得急,所以還有

HTTP協議允許將超文本標記語言 (HTML) 文檔從 Web 服務器傳送到 Web 瀏覽器。HTML 是一種用於創建文檔的標記語言,這些文檔包含到相關信息的鏈接。您可以單擊一個鏈接來訪問其它文檔、圖像或多媒體對象,並獲得關於鏈接項的附加信息。

還是不明白,看看HTTP的請求-響應模型就清楚了

HTTP協議規定的交互很簡單,客戶端向服務器發送包含着信息的請求(絕逼不是整個HTML頁面),服務器接到請求后,根據請求信息生成響應(什么響應都可能,多數是HTML頁面文本),然后把響應發給瀏覽器(如果響應是HTML頁面的話,瀏覽器就加載這個新頁面了)

image

HTTP的請求-響應模型非常簡單,可是初入門的時候我們會誤會它很深

瀏覽器到底向服務器請求什么了

請求不是整個HTML頁面,小朋友們在ASP.NET的codeBehind中經常試圖去Request對象中找頁面的某個DIV,認為請求就是整個HTML頁面,理由也很充分,我能夠找到服務器端控件,怎么就找不到HTML控件呢。訪問百度首頁一下看看瀏覽器究竟請求了什么

當我們在瀏覽器地址欄輸入uri回車或者頁面form提交,瀏覽器會把請求打成包,HTTP請求包(GET/POST等請求方法)由三個部分構成,

<request-line>
<headers>
<blank line>
[<request-body>]

request-line:俗稱請求行,類似於這樣 Get / HTTP /1.0,用來說明請求類型、要訪問的資源路徑(/ 表示跟路徑)以及使用的HTTP版本。

headers: 也就是我們常說的HTTP Headers,訪問百度首頁的時候是一個這樣的東東

image

需要注意的是heasers中包括了該域下的cookie

blank line:這就是一個空行,還是必須的

request-body:這個在post請求時有用,是頁面表單元素的name和value,也就是在Resquest.Forms中能取到的內容,在百度上搜索得到,request body是這樣的

image

是的,HTTP 請求包中就這些內容,沒有什么div啊,什么服務器端控件啊什么的了

為什么能在codeBehind中操作服務器端控件,頁面上卻不能用JavaScript來做

簡單的說服務器端控件是服務器的,服務器並沒有把這個給客戶端,給客戶端的只是服務器端控件render的html文本,所以服務器端找到服務器端控件(你看人家都叫服務器端控件了),客戶端找不到。看起來很高端深奧,實際很簡單,看看服務器交給瀏覽器的是什么,和Request格式類似,Response格式如下

<status-line>
<headers>
<blank line>
[<response-body>]

status-line:表示請求的狀態碼,也就是我們常見的200、301、404、500神馬的

headers:一些響應的數據,還是上面例子,在百度上搜索得到,response headers是這樣的

image

content-type是不是很熟悉?值得注意的是response headers中同樣包含cookie

blank-line:仍舊是不可或缺的空白行

response-body:響應內容,訪問百度首頁response body 大概這樣,其實也就是百度首頁的HTML代碼

image

也就是說,也就是說response body在一般情況下就是得到的就請求頁面的HTML,瀏覽器接收到response后會按照response body重新加載渲染頁面內容。寫過Web Control的同學肯定知道,服務器端控件render成什么了

看一個最簡單的頁面

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="FrontBehind.Default" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <asp:Button ID="btnServer" runat="server" Text="Server" OnClick="btnServer_Click" />
    </div>
    </form>
</body>
</html>

頁面上只有一個服務器端的控件(不要太計較),看看生成的頁面內容

image

服務器端的控件Button經過處理后交給客戶端時已經變成了一個 submit類型的input,頁面上通過JavaScript當然找不到這個服務器端控件了,有興趣同學可以看看Web Control的render control方法,所有的Web Control在Page render的時候都會調用此方法,將服務器端控件按照自己規則render成瀏覽器認識的HTML,然后放到Resoponse中。

瀏覽器從噢乖服務器得到的是全新的HTML文本(不考慮Ajax),沒有其它服務器控件神馬的。

在編碼的時候的頁面和瀏覽器拿到的頁面有什么關系

可能偶同學會對上面的理論有疑問,我們在編程的時候寫的頁面,上面有很多服務器端控件,和最終瀏覽器展示的頁面有什么關系?!這就需要我們講講動態網頁的前世今生。

最開始的時候頁面全都是靜態的HTML文本,瀏覽器做的事情就是告訴服務器我要哪個頁面,服務器傳給你這個頁面,就像張三家開了個磚窯,你需要了就會吼一嗓子,張三,給我塊磚!然后張三扔給你。

但是這樣好單調,有時候頁面內容相當有規律,但是頁面是靜態的就得准被很多頁面,也沒法做到和用戶交互,於是產生了ASP等服務器腳本語言,可以根據用戶參數或者預設條件來修改頁面部分內容,不再簡單返回瀏覽器靜態頁面文件內容,而是根據規則生成HTML文本,然后返回給瀏覽器。

后來面向對象的普及及模塊兒化編程等等思想的影響,有一些常用的規則,比如畫出個日歷啊我們可以寫成一個單獨的模塊兒,然后通過指令使其嵌在頁面內,用的時候寫一條指令就可以了,這就是ASP.NET 中例如Button等的Web Control,也就是服務器端控件。

如果服務器判斷出瀏覽器請求的是帶有服務器腳本的頁面的時候(一般根據拓展名或者Map關系判斷),就會交給固定類型腳本的“解釋器”去處理這些腳本,轉換成HTML語句,然后返回給客戶端。

所以瀏覽器呈現的頁面是我們根據開發時候定義的規則,動態生成的HTML文本加載渲染的結果

HTTP工作流程

  1. 一次HTTP操作稱為一個事務,其工作過程可分為四步:
    首先客戶機與服務器需要建立連接。只要單擊某個超級鏈接,HTTP的工作開始。
    建立連接后,客戶機發送一個請求給服務器,請求方式的格式為:統一資源標識符(URL)、協議版本號,后邊是MIME信息包括請求修飾符、客戶機信息和可能的內容。
    服務器接到請求后,給予相應的響應信息,其格式為一個狀態行,包括信息的協議版本號、一個成功或錯誤的代碼,后邊是MIME信息包括服務器信息、實體信息和可能的內容。
    客戶端接收服務器所返回的信息通過瀏覽器顯示在用戶的顯示屏上,然后客戶機與服務器斷開連接。

HTTP特點

通過上面的說明可以看出HTTP協議有幾個特征

1.HTTP協議永遠都是客戶端發起請求,服務器回送響應。這樣就限制了使用HTTP協議,無法實現在客戶端沒有發起請求的時候,服務器將消息推送給客戶端。必須是客戶端給服務器要,而不能服務器主動給客戶端。

2.HTTP協議是一個無狀態的協議,同一個客戶端的這次請求和上次請求是沒有對應關系。也就是說你連續兩次訪問百度,這兩次之間沒有什么關系(不考慮緩存),不會像你去親戚家串門,上次去了,這次就認識你了。要想讓它們有關系我們注意到request header和resonse header都有cookie,Session等客戶端狀態維護就是基於此實現的。

3.在請求時並不是頁面所有內容都被發往服務器

4.在客戶端就已經沒有什么服務器端控件、方法、屬性了,只有HTML文本

幾個問題

總而言之有一句需要注意:HTTP協議並不是瀏覽器把整個頁面發給服務器,然后讓服務器做少許改動傳回給瀏覽器,而是瀏覽器發送少量數據參數傳給服務器,服務器根據特定頁面規則和瀏覽器參數生成全新頁面傳回給瀏覽器,瀏覽器更新加載這個全新頁面(不考慮Ajax)。瀏覽器呈現的頁面和服務器之間並不能通過所謂調用來交互。

理論知識就這么多,下一篇中就要即使一下開頭提的三個問題了,修改羅列一下

1.服務器端如何影響客戶端元素與行為

2.客戶端如何”調用“服務器端方法

3.JavaScript如何操作服務器控件render的HTML,以實現交互

PS:如果還有同學對HTTP協議有疑惑,可以看看之前為了跟小伙兒伴們將HTTP而寫的一個課件


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM