由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页面的话,浏览器就加载这个新页面了)
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啊,什么服务器端控件啊什么的了
为什么能在codeBehind中操作服务器端控件,页面上却不能用JavaScript来做
简单的说服务器端控件是服务器的,服务器并没有把这个给客户端,给客户端的只是服务器端控件render的html文本,所以服务器端找到服务器端控件(你看人家都叫服务器端控件了),客户端找不到。看起来很高端深奥,实际很简单,看看服务器交给浏览器的是什么,和Request格式类似,Response格式如下
<status-line>
<headers>
<blank 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成什么了
看一个最简单的页面
<%@ 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工作流程
- 一次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而写的一个课件