工作兩年多了,我會經常嘗試給公司小夥伴兒們解決一些問題,幾個月下來我發現初入公司的小朋友最愛問的問題就三個
1. 我想前台調用背景的XXX方法怎麼弄啊?
2. 我想背景調用前台的XXX JavaScript方法怎麼弄啊?
3. 怎麼用JavaScript找到/建立/修改XXX這個伺服器端控件啊?
每次我會跟小朋友分析一下為什麼會有如此荒誕不經的想法,然後說原來你做XXX啊,那你應該這樣,可發現這種模式太失敗了,因為隔幾天我又會聽到小朋友還是有類似的疑惑。
我決定以後再有誰問這個問題,我就讓誰給我講講HTTP協定,幾次過後效果非凡啊,看看這兩個問題和HTTP協定有什麼關系吧
HTTP協定即超文本傳輸協定 (HTTP-Hypertext transfer protocol) 是分布式,協作式,超媒體系統應用之間的通信協定。是網際網路(world wide web)交換資訊的基礎。是一種詳細規定了浏覽器和網際網路伺服器之間互相通信的規則,通過網際網路傳送網際網路文檔的資料傳送協定。
這是從百度上抄來的定義,感覺味同嚼蠟,反正我要是問人什麼是HTTP,要是這麼回答我,我肯定得急,是以還有
還是不明白,看看HTTP的請求-響應模型就清楚了
HTTP協定規定的互動很簡單,用戶端向伺服器發送包含着資訊的請求(絕逼不是整個HTML頁面),伺服器接到請求後,根據請求資訊生成響應(什麼響應都可能,多數是HTML頁面文本),然後把響應發給浏覽器(如果響應是HTML頁面的話,浏覽器就加載這個新頁面了)

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,通路百度首頁的時候是一個這樣的東東
需要注意的是heasers中包括了該域下的cookie
blank line:這就是一個空行,還是必須的
request-body:這個在post請求時有用,是頁面表單元素的name和value,也就是在Resquest.Forms中能取到的内容,在百度上搜尋得到,request body是這樣的
是的,HTTP 請求包中就這些内容,沒有什麼div啊,什麼伺服器端控件啊什麼的了
簡單的說伺服器端控件是伺服器的,伺服器并沒有把這個給用戶端,給用戶端的隻是伺服器端控件render的html文本,是以伺服器端找到伺服器端控件(你看人家都叫伺服器端控件了),用戶端找不到。看起來很高端深奧,實際很簡單,看看伺服器交給浏覽器的是什麼,和Request格式類似,Response格式如下
<status-line>
[<response-body>]
status-line:表示請求的狀态碼,也就是我們常見的200、301、404、500神馬的
headers:一些響應的資料,還是上面例子,在百度上搜尋得到,response headers是這樣的
content-type是不是很熟悉?值得注意的是response headers中同樣包含cookie
blank-line:仍舊是不可或缺的空白行
response-body:響應内容,通路百度首頁response body 大概這樣,其實也就是百度首頁的HTML代碼
也就是說,也就是說response body在一般情況下就是得到的就請求頁面的HTML,浏覽器接收到response後會按照response body重新加載渲染頁面内容。寫過Web Control的同學肯定知道,伺服器端控件render成什麼了
看一個最簡單的頁面
頁面上隻有一個伺服器端的控件(不要太計較),看看生成的頁面内容
伺服器端的控件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操作稱為一個事務,其工作過程可分為四步:
首先客戶機與伺服器需要建立連接配接。隻要單擊某個超級連結,HTTP的工作開始。
建立連接配接後,客戶機發送一個請求給伺服器,請求方式的格式為:統一資源辨別符(URL)、協定版本号,後邊是MIME資訊包括請求修飾符、客戶機資訊和可能的内容。
伺服器接到請求後,給予相應的響應資訊,其格式為一個狀态行,包括資訊的協定版本号、一個成功或錯誤的代碼,後邊是MIME資訊包括伺服器資訊、實體資訊和可能的内容。
用戶端接收伺服器所傳回的資訊通過浏覽器顯示在使用者的顯示屏上,然後客戶機與伺服器斷開連接配接。
通過上面的說明可以看出HTTP協定有幾個特征
1.HTTP協定永遠都是用戶端發起請求,伺服器回送響應。這樣就限制了使用HTTP協定,無法實作在用戶端沒有發起請求的時候,伺服器将消息推送給用戶端。必須是用戶端給伺服器要,而不能伺服器主動給用戶端。
2.HTTP協定是一個無狀态的協定,同一個用戶端的這次請求和上次請求是沒有對應關系。也就是說你連續兩次通路百度,這兩次之間沒有什麼關系(不考慮緩存),不會像你去親戚家串門,上次去了,這次就認識你了。要想讓它們有關系我們注意到request header和resonse header都有cookie,Session等用戶端狀态維護就是基于此實作的。
3.在請求時并不是頁面所有内容都被發往伺服器
4.在用戶端就已經沒有什麼伺服器端控件、方法、屬性了,隻有HTML文本
總而言之有一句需要注意:HTTP協定并不是浏覽器把整個頁面發給伺服器,然後讓伺服器做少許改動傳回給浏覽器,而是浏覽器發送少量資料參數傳給伺服器,伺服器根據特定頁面規則和浏覽器參數生成全新頁面傳回給浏覽器,浏覽器更新加載這個全新頁面(不考慮Ajax)。浏覽器呈現的頁面和伺服器之間并不能通過所謂調用來互動。
理論知識就這麼多,下一篇中就要即使一下開頭提的三個問題了,修改羅列一下
1.伺服器端如何影響用戶端元素與行為
2.用戶端如何”調用“伺服器端方法
3.JavaScript如何操作伺服器控件render的HTML,以實作互動
本文轉自魏瓊東部落格園部落格,原文連結: 本文轉自魏瓊東部落格園部落格,原文連結:,如需轉載請自行聯系原作者,如需轉載請自行聯系原作者