工做兩年多了,我會常常嘗試給公司小夥伴兒們解決一些問題,幾個月下來我發現初入公司的小朋友最愛問的問題就三個html
1. 我想前臺調用後臺的XXX方法怎麼弄啊?web
2. 我想後臺調用前臺的XXX JavaScript方法怎麼弄啊?編程
3. 怎麼用JavaScript找到/建立/修改XXX這個服務器端控件啊?瀏覽器
每次我會跟小朋友分析一下爲何會有如此荒誕不經的想法,而後說原來你作XXX啊,那你應該這樣,可發現這種模式太失敗了,由於隔幾天我又會聽到小朋友仍是有相似的疑惑。緩存
我決定之後再有誰問這個問題,我就讓誰給我講講HTTP協議,幾回事後效果非凡啊,看看這兩個問題和HTTP協議有什麼關係吧服務器
HTTP協議即超文本傳輸協議 (HTTP-Hypertext transfer protocol) 是分佈式,協做式,超媒體系統應用之間的通訊協議。是萬維網(world wide web)交換信息的基礎。是一種詳細規定了瀏覽器和萬維網服務器之間互相通訊的規則,經過因特網傳送萬維網文檔的數據傳送協議。cookie
這是從百度上抄來的定義,感受味同嚼蠟,反正我要是問人什麼是HTTP,要是這麼回答我,我確定得急,因此還有分佈式
HTTP協議容許將超文本標記語言 (HTML) 文檔從 Web 服務器傳送到 Web 瀏覽器。HTML 是一種用於建立文檔的標記語言,這些文檔包含到相關信息的連接。您能夠單擊一個連接來訪問其它文檔、圖像或多媒體對象,並得到關於連接項的附加信息。ide
仍是不明白,看看HTTP的請求-響應模型就清楚了post
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>
<headers>
<blank line>
[<response-body>]
status-line:表示請求的狀態碼,也就是咱們常見的200、30一、40四、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成什麼了
看一個最簡單的頁面
<%@ 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>
頁面上只有一個服務器端的控件(不要太計較),看看生成的頁面內容
服務器端的控件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協議,無法實如今客戶端沒有發起請求的時候,服務器將消息推送給客戶端。必須是客戶端給服務器要,而不能服務器主動給客戶端。
2.HTTP協議是一個無狀態的協議,同一個客戶端的此次請求和上次請求是沒有對應關係。也就是說你連續兩次訪問百度,這兩次之間沒有什麼關係(不考慮緩存),不會像你去親戚家串門,上次去了,此次就認識你了。要想讓它們有關係咱們注意到request header和resonse header都有cookie,Session等客戶端狀態維護就是基於此實現的。
3.在請求時並非頁面全部內容都被髮往服務器
4.在客戶端就已經沒有什麼服務器端控件、方法、屬性了,只有HTML文本
總而言之有一句須要注意:HTTP協議並非瀏覽器把整個頁面發給服務器,而後讓服務器作少量改動傳回給瀏覽器,而是瀏覽器發送少許數據參數傳給服務器,服務器根據特定頁面規則和瀏覽器參數生成全新頁面傳回給瀏覽器,瀏覽器更新加載這個全新頁面(不考慮Ajax)。瀏覽器呈現的頁面和服務器之間並不能經過所謂調用來交互。
理論知識就這麼多,下一篇中就要即便一下開頭提的三個問題了,修改羅列一下
1.服務器端如何影響客戶端元素與行爲
2.客戶端如何」調用「服務器端方法
3.JavaScript如何操做服務器控件render的HTML,以實現交互
PS:若是還有同窗對HTTP協議有疑惑,能夠看看以前爲了跟小夥兒伴們將HTTP而寫的一個課件