一次完整的HTTP通信过程中,浏览器与web服务器的7个步骤:
1.建立TCP连接
在HTTP工作开始前,浏览器首先要通过网络与服务器建立连接,该连接是通过TCP来完成的。HTTP是比TCP更高层次的应用层协议,根据规则,只有底层协议建立之后才能进行更高层次协议的连接。
2.浏览器向服务器发送请求命令
一旦建立了TCP连接,浏览器就会想服务器发送请求命令。例如:GET/sample/hello.html HTTP/1.1
3.浏览器发送请求头信息
浏览器发送请求命令之后,还要以头信息的形式向服务器发送一些别的信息,之后浏览器发送了空白行来通知服务器,表示已经结束了该头信息的发送。
4.服务器应答
客户端向服务器发送请求之后,服务器会向客户端会送应答。
HTTP/1.1 200 OK
应答的第一部分是协议的版本号和应答状态码
5. 服务器发送应答头信息
正如客户端会随同请求发送自身信息一样,服务器也会随同应答向用户发送关于它自己的数据和被请求的文档。
6.服务器向浏览器发送数据
服务器向浏览器发送头信息后,它会发送一个空白行来表示头信息的发送到此为结束,接着,它就已Content-Type应答头信息所描述的格式发送用户所请求的实际数据。
7.服务器关闭TCP连接
一般情况下,一旦服务器向浏览器发送了应答数据,就要关闭TCP连接,然后如果浏览器或者服务器在其头信息加入了这行信息:
Connection:keep-alive
TCP连接在发送后将仍然保持打开状态,于是,浏览器可以继续通过相同的连接发送请求。保持连接节省了为每个请求建立新连接所花费的时间,还节约了网络宽带。
HTTP报文是面向文本的,报文中的每一个字段都是一些ASCII码串,各个字段的长度是不确定的,HTTP有两类报文:请求报文和响应报文
如下图所示:
一个HTTP请求报文是由请求行(request line)、请求头部(header)、空行和请求数据4个部分组成。
请求行由请求方法字段、URL字段和HTTP协议版本字段3个字段组成,它们用空格分隔。
例如:GET /index.html HTTP/1.1
HTTP协议的请求方法有GET、POST、HEAD、DELETE、OPTIONS、TRACE、CONNECT。
而常见的有以下几种:
最常见的一种请求,当客户端从服务器中读取文档时,当点击网页上的链接或者通过在浏览器的地址栏输入网址来浏览页面时,都是使用的GET方式。GET方法要求服务器将URL定位的资源放在响应报文数据部分,回送给客户端。使用GET方法时,请求参数和对应的值放在URL后面,利用一个问号'?'代表URL的结尾和请求参数的开始。传递参数受到长度限制。
例如: GET /index.jsp?id=100&op=bind,这样通过GET方式传递的数据直接显示在地址中。
下面是一个请求:
1 GET /search?hl=zh-CN&source=hp&q=domety&aq=f&oq= HTTP/1.1
2 Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/vnd.ms-excel, application/vnd.ms-powerpoint,
3 application/msword, application/x-silverlight, application/x-shockwave-flash, */*
4 Referer: <a href="http://www.google.cn/">http://www.google.cn/</a>
5 Accept-Language: zh-cn
6 Accept-Encoding: gzip, deflate
7 User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727; TheWorld)
8 Host: <a href="http://www.google.cn">www.google.cn</a>
9 Connection: Keep-Alive
10 Cookie: PREF=ID=80a06da87be9ae3c:U=f7167333e2c3b714:NW=1:TM=1261551909:LM=1261551917:S=ybYcq2wpfefs4V9g;
11 NID=31=ojj8d-IygaEtSxLgaJmqSjVhCspkviJrB6omjamNrSm8lZhKy_yMfO2M4QMRKcH1g0iQv9u-2hfBW7bUFwVh7pGaRUb0RnHcJU37y-
12 FxlRugatx63JLv7CWMD6UB_O_r
可以看到,GET方式的请求一般不包含“请求内容”部分,请求数据以地址的形式表现在请求行。地址链接如下:
<a href="http://www.google.cn/search?hl=zh-CN&source=hp&q=domety&aq=f&oq=">http://www.google.cn/search?hl=zh-CN&source=hp
&q=domety&aq=f&oq=</a>
地址中”?”之后的部分就是通过GET发送的请求数据,我们可以在地址栏中清楚的看到,各个数据之间用”&”符号隔开。显然,这种方式不适合传送私密数据。另外,由于不同的浏览器对地址的字符限制也有所不同,一般最多只能识别1024个字符,所以如果需要传送大量数据的时候,也不适合使用GET方式。
对于不适合使用GET方式的情况,可以考虑使用POST方式,因为使用POST方法可以允许客户端给服务器提供信息更多一些。POST方法将请求参数封装在HTTP请求数据中,以名称/值的形式出现,可以传输大量数据,这样POST方式对传送的数据大小没有限制,而且也不会显示在URL中。还以上面的搜索domety为例,如果使用POST方式的话,格式如下:
POST /search HTTP/1.1
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/vnd.ms-excel, application/vnd.ms-powerpoint,
application/msword, application/x-silverlight, application/x-shockwave-flash, */*
Referer: <a href="http://www.google.cn/">http://www.google.cn/</a>
Accept-Language: zh-cn
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727; TheWorld)
Host: <a href="http://www.google.cn">www.google.cn</a>
Connection: Keep-Alive
Cookie: PREF=ID=80a06da87be9ae3c:U=f7167333e2c3b714:NW=1:TM=1261551909:LM=1261551917:S=ybYcq2wpfefs4V9g;
NID=31=ojj8d-IygaEtSxLgaJmqSjVhCspkviJrB6omjamNrSm8lZhKy_yMfO2M4QMRKcH1g0iQv9u-2hfBW7bUFwVh7pGaRUb0RnHcJU37y-
FxlRugatx63JLv7CWMD6UB_O_r
hl=zh-CN&source=hp&q=domety
可以看到,POST方式请求行中不包含数据字符串,这些数据保存在”请求内容”部分,各数据之间也是使用”&”符号隔开。POST方式大多用于页 面的表单中。因为POST也能完成GET的功能,因此多数人在设计表单的时候一律都使用POST方式,其实这是一个误区。GET方式也有自己的特点和优 势,我们应该根据不同的情况来选择是使用GET还是使用POST。
HEAD就像GET,只不过服务端接受到HEAD请求后只返回响应头,而不会发送响应内容。当我们只需要查看某个页面的状态的时候,使用HEAD是非常高效的,因为在传输的过程中省去了页面内容。
报文头:
④是HTTP的报文头,报文头包含若干个属性,格式为“属性名:属性值”,服务端据此获取客户端的信息。 ⑤是报文体,它将一个页面表单中的组件值通过param1=value1¶m2=value2的键值对形式编码成一个格式化串,它承载多个请求参数的数据。不但报文体可以传递请求参数,请求URL也可以通过类似于“/aremiyi/wonter.html? param1=value1¶m2=value2”的方式传递请求参数。
消息头:
accept:浏览器通过这个头告诉浏览器,他所支持的数据类型
Accept-Charset: 浏览器通过这个头告诉服务器,它支持哪种字符集
Accept-Encoding:浏览器通过这个头告诉服务器,支持的压缩格式
Accept-Language:浏览器通过这个头告诉服务器,它的语言环境
Host:浏览器通过这个头告诉服务器,想访问哪台主机
If-Modified-Since: 浏览器通过这个头告诉服务器,缓存数据的时间
Referer:浏览器通过这个头告诉服务器,客户机是哪个页面来的 防盗链
Connection:浏览器通过这个头告诉服务器,请求完后是断开链接还是何持链接
响应报文:
目前,对于同一个域名,大多数浏览器允许同时建立6个持久连接。
1xx: 信息性状态码
100, 101
2xx: 成功状态码
200:OK
3xx: 重定向状态码
301: 永久重定向, Location响应首部的值仍为当前URL,因此为隐藏重定向;
302: 临时重定向,显式重定向, Location响应首部的值为新的URL
304:Not Modified 未修改,比如本地缓存的资源文件和服务器上比较时,发现并没有修改,服务器返回一个304状态码,
告诉浏览器,你不用请求该资源,直接使用本地的资源即可。
4xx: 客户端错误状态码
404: Not Found 请求的URL资源并不存在
5xx: 服务器端错误状态码
500: Internal Server Error 服务器内部错误
502: Bad Gateway 前面代理服务器联系不到后端的服务器时出现
504:Gateway Timeout 这个是代理能联系到后端的服务器,但是后端的服务器在规定的时间内没有给代理服务器响应
Location: 服务器通过这个头,来告诉浏览器跳到哪里
Server:服务器通过这个头,告诉浏览器服务器的型号
Content-Encoding:服务器通过这个头,告诉浏览器,数据的压缩格式
Content-Length: 服务器通过这个头,告诉浏览器回送数据的长度
Content-Language: 服务器通过这个头,告诉浏览器语言环境
Content-Type:服务器通过这个头,告诉浏览器回送数据的类型
Refresh:服务器通过这个头,告诉浏览器定时刷新
Content-Disposition: 服务器通过这个头,告诉浏览器以下载方式打数据
Transfer-Encoding:服务器通过这个头,告诉浏览器数据是以分块方式回送的
Expires: -1 控制浏览器不要缓存 Cache-Control: no-cache Pragma: no-cache
1.GET提交,请求的数据会附在URL之后(就是把数据放置在HTTP协议头<request-line>中), 以?分割URL和传输数据,多个参数用&连接;例如:login.action?name=hyddd& password=idontknow&verify=%E4%BD%A0 %E5%A5%BD。如果数据是英文字母/数字,原样发送,如果是空格,转换为+,如果是中文/其他字符,则直接把字符串用BASE64加密,得出如: %E4%BD%A0%E5%A5%BD,其中%XX中的XX为该符号以16进制表示的ASCII。
POST提交:把提交的数据放置在是HTTP包的包体<request-body>中。上文示例中红色字体标明的就是实际的传输数据
因此,GET提交的数据会在地址栏中显示出来,而POST提交,地址栏不会改变。
2.传输数据的大小:
首先声明,HTTP协议没有对传输的数据大小进行限制,HTTP协议规范也没有对URL长度进行限制。 而在实际开发中存在的限制主要有:
GET:特定浏览器和服务器对URL长度有限制,例如IE对URL长度的限制是2083字节(2K+35)。对于其他浏览器,如Netscape、FireFox等,理论上没有长度限制,其限制取决于操作系统的支持。
因此对于GET提交时,传输数据就会受到URL长度的限制。
POST:由于不是通过URL传值,理论上数据不受限。但实际各个WEB服务器会规定对post提交数据大小进行限制,Apache、IIS6都有各自的配置。
3.安全性:
POST的安全性要比GET的安全性高。注意:这里所说的安全性和上面GET提到的“安全”不是同个概念。上面“安全”的含义仅仅是不作数据修改,而这里安全的含义是真正的Security的含义,比如:通过GET提交数据,用户名和密码将明文出现在URL上,因为(1)登录页面有可能被浏览器缓存, (2)其他人查看浏览器的历史纪录,那么别人就可以拿到你的账号和密码了。