hello,every body!申请博客已经好久了,这是我的第一篇文章。写文章的动力,来源于宋大师(下文会多次提到他.以宋桑来代替)的鼓舞。上周六,我与我的偶像宋桑一起喝咖啡,聊了一下彼此的近况。宋桑鼓舞我,让我把自己的想法、思路、目标、记录下来,要学会总结。当我听说,宋桑通过写博客,认识了好多志同道合的朋友时,我内心开始跃跃欲试了。在写这篇文章之前,我有必要给大家介绍一下宋桑。
去年的一个偶然机会,我来宋桑的公司面试,恰巧它是面试官。当时并不知道他是个技术大牛,我凭着一点点微薄的技术积累“蒙混过关”。(之后有跟他聊过,他说我的态度很好,是我的态度令他接受了我。看来为人处世万万不可骄傲自大、目空一切。为人要低调,要做有本事无脾气的头等人)在之后的工作中,我慢慢发现了他的”神秘身份”。他Microsoft sqlserver MVP,曾经受邀去位于Seattle的Microsoft总部参加活动。他还是一个译者,英文功底是顶嘎嘎的,(这一点,深深的影响了我,让我对英文着了魔。)他曾经翻译过很多sqlserver原著书籍。他也是sqlserver高级讲师,曾在很多大型企业进行过演讲。他可以把很深奥的东西,让你很轻松的接受。这一点,是很不容易的。做技术的,在沟通表达上可以有这么强悍的能力,实属罕见。在这么多的光环照耀下,依然这么谦虚好学,我打心眼里佩服他。最重要的一点,对我这个IT小弟很是照顾。给我讲了好多知识,思想,方法论。我很感谢他对我各种帮助,非常感谢他。
好了,书归正传。我今天想写一篇关于HTTP协议的文章,因为昨天刚看过宋桑的文章(漫谈HTTP),感觉自己应该总结思考一下。这篇文章,权当自己总结思考笔记。因为第一次写文章,肯定会有很多不全面的地方。欢迎各位博友吐槽、拍砖。
读<漫谈HTTP>有感
原文出处: www.cnblogs.com/CareySon
我想用几个问题来引出我的这篇文章内容,OK,上问题:
Questions:
在一个网络中,数据传输需要面临三个问题
1.客户端如何知道所要请求信息的地址?
2.客户端知道请求信息的地址后,是如何进行传输的?
3.获得的信息是以何种形式组织显示的?
Answers:
回答以上三个问题,会牵扯出3个技术点
1.统一资源定位符(URI)
2.超文本传输(HTTP)协议
3.超文本标记语言(HTML)
HTTP的三个时期
今天,我们主要讲解超文本传输协议。HTTP协议,像个呱呱落地的孩子。她需要经历三个时期,童年、青年、壮年。接下来,让我们一下来看看她的三个时期吧。
童年:
童年时快乐的,快的原因有一部分是因为,我们那时候思想单纯,我们生活简单。HTTP的童年也是快乐的,因为她非常简单。HTTP0.9,就是HTTP的童年。她有多么简单呢?给大家一个例子:
Get www.cnblogs.com HTTP0.9
简单么?她只有一个请求行,只有Get方法,没有HTTP头、没有错误码、只接受文本类型。呵呵,大家是不是感到她很弱小?其实不然,宋桑说过,看问题不要开狭隘,要把问题放在周围环境中去看。研究技术也一样,不要上来就去看API,你要去看这个技术出现的环境,技术的历史,为什么出现?在了解这些问题之后,再去学习技术,你会有种游刃有余的感觉。(这种感觉,目前我还没有体验过。hah)HTTP 0.9,在当时已经可以满足需要了。
青年:
随着时间的流逝,HTTP从童年走入了青年。大家都会有这种感觉,一个人的童年与青年给人的感觉判若两人。HTTP也不例外,进入青年后,她发生了质的变化,正所谓,女大十八变,越变越美丽.
HTTP1.0,最重要的一点,她支持Post请求。这一点,促使客户端通过HTML向服务器发送请求成为可能。HTTP1.0还引入了HTTP头,使得HTTP可以返回错误码,HTTP所接受的内容不再局限于文本类型。除此之外还允许保持连接。即TCP连接后,可以多次通信。(Note:下文会相信讲解.)
壮年:
HTTP终于长成亭亭玉立的大姑娘了,所以HTTP走入了她的壮年时期。相对于HTTP1.0,HTTP1.1的改变就没有那么革命性了。HTTP1.1,引入了Host头。上例子:
Get /VitoCorleone/
Host www.cnblogs.com
Get 后面只要相对路径就可以了。不要小看这个Host头,它的出现,使得web上的一台计算机可以拥有多个域名。否则多个域名指向同一个IP会造成混乱。此外,还引入了Range头。
使得客户端通过HTTP下载时,只下载内容的一部分,这使得多线程成为可能.(我不明白这句话,有机会请宋桑讲一下!)
HTTP的网络层次
在Internet中,所有的传输都是通过TCP/IP进行的。
通过此图,大家可以发现HTTP是建立在传输层(TCP)之上的。只有当TCP建立连接之后,HTTP才可以进行通信。TCP的建立连接,会经过所谓的”三次握手”。上图:
TCP连接后,HTTP就可以通信了。值得注意的一点是,面对连接。即,HTTP在通信时,TCP是保持连接的。上图:
大家可以从图中发现,我只是单纯的请求 /webform1,但是浏览器发出了多个请求。这是怎么回事呢?原来,浏览器解析收到的HTML时,发现需要下载的文件,它就会再次发出HTTP请求。例如图中的请求css文件的请求。这多请求,只要TCP连接一次就好。这就是所谓的持久连接。
HTTP请求(HTTP Request)
http请求是客户端向服务器发送的信息,这个信息包括3个部分:
1.请求行:
比如请求我的博客地址 Get www.cnblogs.com/wangwenxin03 HTTP1.1
请求行的格式是固定的,第一部分请求方式,第二部分请地址,第三部分HTTP版本
2.HTTP头
HTTP头可以分为四种类型,但是在HTTP请求中,只能出现3中类型的头。
通用头(general header)
实体头(entity header)Note:因为get请求没有内容,所以在get请求中,不会出现实体头。
请求头(request header)Note:request header 只能出现在HTTP请求中
3.内容
这部分只有在Post请求时才会出现。Get请求没有内容。
HTTP请求的方法
http请求除了Get、Post、方法外,还有Delete、Put、Trace、Connect 等。这里着重说一下,Get、Post的区别。之前,一直认为,Get与Post的区别仅仅是Get传输数据的大小、传输的安全性较Post少、低。但是看过宋桑的文章之后,我终于明白了。最本质的区别在于,Post有上面提到的第三部分”内容”。而Get却没有。虽然Get可以通过QueryString进行传输信息。但是它违背了Get的本意。这些通过QueryString传送的信息,在服务器看来只是当作传输数据的参数而已。而Post是客户端向服务器传输信息的方式。
HTTP响应(HTTP Response)
服务器在接受到客户端的请求后,会进行处理,返回客户端所要的内容。返回的可能是一个静态页,也可能是经过ASP.NET、JSP、PHP处理过的。再返回这些内容时,也会返回一个响应。HTTP响应在结构上,与上面提到的HTTP Request很类似。也是由三个部分组成:
1.状态行:
HTTP/1.1 200 OK
状态行格式也是固定的,第一部分,HTTP版本,第二部分,状态码,第三部分,状态码描述。其实第二部分与第三部分可以看成是一个部分。
状态码分类:
信息类(100-199)
响应成功类(200-299)
重定向类(300-399)
客户端错误类(400-499)
服务端错误类(500-599)
2.HTTP头:
在HTTP响应中只可以出现三种类型的HTTP头:
通用头(general header)
实体头(entity header)
响应头(response header)Note:response header,只能出现在HTTP Response中
3.内容
返回客户端所需要的东西,可以是图片,文本,等格式。
既然可以是图片,也可以是文本,还可以是其他类型的内容。那么浏览器是如何识别的呢?原来浏览器是通过媒体类型(media type)来判断的,对应的具体事物上,就是Content-type这个HTTP头。Media type 的类型为 大类/小类 例子:text/html
The Internet Assign Authority ----互联网数字分配机构,定义了8个大类:
application---(比如:application/vnd.ms-excel)
audio----(比如:audio/mp3)
image----(比如image/png)
message---(比如message/htttp)
model---(比如model/vrml)
multipart---(比如multipart/form-data)
text----(比如text/html)
video----(比如video/quicktime)
HTTP头(HTTP Header)
刚才上文在讲HTTP Request、HTTP Response时,提到了HTTP头。接下来,让我们一起来学习一下吧。
http头,可以分为四大类:
1.通用头(general header)
通用头可以出现在HTTP Request中,也可以出现在HTTP Response中。它主要是描述HTTP协议本事,例如描述HTTP是否持续连接的 connection头,http发送的日期的date头。描述HTTP所在TCP连接的时间头keep-alive头。用于缓存控制的cache-control头。
2.实体头(entity header)Node:Get没有内容,所以没有实体头。
实体头可以出现在HTTP Request、HTTP Response 中。它主要是描发送信息的。content-type content-length,等等。
3.请求头(request header)
引用宋桑原文的一句话,来描述请求头.” 请求头是那些由客户端发往服务端以便帮助服务端更好的满足客户端请求的头。请求头只能出现在HTTP请求中。”比如用来告诉服务器只能接受的类型的Accept头。发送Cookie的Cookie头,显示主机域的Host头。
4.响应头(Response header)
响应头,描述响应本身的信息。但是不包括HTTP响应的第三部分--内容。(这部分内容由实体头负责)例如,描述服务器信息的Server头,设置Cookie的Set-Cookie头、告诉客户端可以部分请求的Accept-Ranges头、可以定时刷新的Refresh头,当遇到503错误自动重试的Retry-After头。
状态保持
HTTP是无状态而言的,也就是说,每一次请求,服务器不知道是来自同一个客户端还是来自 不同的客户端。我们需要用一些方法,来使服务器知道请求是来自哪个客户端。
那么我们需要什么方法来实现呢?
1.通过Cooke保持状态
HTTP可以通过Cookie来保持状态。图片的请求,如果通过Cookie来保持状态。如下图:
2.通过表单变量保持状态
我们也可通过表单变量来保持,例如ASP.NET中,就是通过一个叫做ViewState的Input=’hide’的框来保持状态的。例如:
<input type=’hide’ value=”this a client state”/>
3.通过QueryString保持状态
这个方法与上面讲到的方法,原理是一样的。querystring 将信息保存在所请求的地址末尾来向服务器传送。例如:
终于写完了,好多地方都是原文的原话。整篇文章写下来,自己的头绪清晰了,对HTTP有了全新的认识。最后,还是要感谢一下原文作者-宋桑!谢谢!