本篇作为学习servlet的前提,http协议是学习JavaWeb开发的基石,不深入了解http协议,就不能说掌握了JavaWeb开发。

  HTTP协议有两个版本:HTTP1.0和HTTP1.1,那么有什么区别呢?

  HTTP协议1.0中,客户端与web服务端建立连接之后,只能获得一个资源,如果还想获得资源,那么久得重新连接。

  而HTTP1.1协议则是客户端和web服务端连接之后,在这个连接上可以进行多个资源的传输。

  关于这个HTTP1.1和HTTP1.0协议的区别可以使用Telnet进行验证。如果在命令行窗口cmd中提示“Telnet”不是Windows命令,则需要从【控制面板】--->【程序】--->【打开或关闭Windows功能】中勾选【Telnet客户端】。(Telnet是微软自带的可进行远程连接的工具)

  开始在cmd中输入“telnet  主机名   端口号”,如输入:“telnet  localhost  8080”:

  

  默认情况下,Telnet是你输一个字符,它就发一个字符,并且不回显,如果需要回显,必须在输入以上命令启动Telnet后,同时按下【Ctrl】+【}】打开回显,并且最好是在记事本中先敲好要访问的命令,再复制进cmd中。

现在我用Telnet来访问我的Tomcat服务器,在我Tomcat服务器的【webapps】目录下有一个web应用,web应用所在目录名为【telnetTest】,其下有一个test.html文件,内容为“long live sd”,现在我使用Telnet以HTTP1.0协议去访问(访问之前记得开启Tomcat服务器哦):

  打开回显,并回车一次,并输入请求行和主机(主机一定要有,无值则默认为本机),会看到如下:

  

使用HTTP1.0协议则是服务器将请求的资源传输回客户端后立即将连接断开,而使用HTTP1.1协议的情景如下图所示:

  

  可见,HTTP1.1在将资源回传给客户端之后,不会立即断开连接,也就是说在未超时的时间内,客户端还可以向服务器请求资源,因为这个连接还未断开!(说实话Telnet实在太难用,还是用HttpWatch观察比较好。。。)

  当然现在基本都是HTTP1.1协议,HTTP1.0协议已经基本不用了。。。因此我们所说的HTTP协议通常都是指HTTP1.1协议。

=============================================================================

  一个有关HTTP协议的小问题:

  一个web页面中,假设有三个<img>标签,这三个<img>标签引用了图片,当客户端访问这个web页面时,客户端总共会向服务器发生几次HTTP请求?

  答案是四次,第一次是请求HTML页面,服务器将HTML页面传给浏览器后,浏览器开始解析HTML页面中的内容,而每次解析到<img>标签时,又要根据该标签的图片引用地址重新向服务器请求图片资源。所以总共有四次HTTP请求。因此在web优化中最重要的是要减少客户端向服务器的http请求次数。

=============================================================================

  首先来看HTTP协议的请求内容:

  一个完整的HTTP请求包含了如下内容:一个请求行,若干消息头,和空格之后的实体内容,如下图:

  

  请求行:请求行的最开始为请求方式,原来总共有七种,现在只剩下GET(默认)和POST两种方式,其中POST方式又只用于表单的安全提交,而其他一般都是以GET方式来进行请求。

  GET和POST方式的区别主要表现在数据的传递上:

  如果请求方式为GET方式,则可以在请求的URL地址后以“?”的形式带上交给服务器的数据,多个数据之间以“&”隔开,例如:

GET  /mail/1.html?username=admin&password=123 HTTP/1.1

但GET方式后附带的数据是有限的,不能超过1K。

如果请求方式为POST方式,可以在请求的实体内容中装载数据,而这个数据的装载大小是无限制的。

常用的消息头有很多,下图是一个示例:

  

  Accept: 用于告诉服务器,客户端所支持的数据类型(MIME类型)。

  Accept-Charset: 用于告诉服务器,客户端所采用的码表。

  Accept-Encoding: 用于告诉服务器,客户端所支持的数据压缩格式。

  Accept-Language: 用于告诉服务器,客户端采用的语言环境(国际化)。

  Host: 用于告诉服务器,客户端想访问服务器哪台主机。

  If-Modified-Since: 用于告诉服务器,客户端对于资源的最后缓存时间。

  Referer: 用于告诉服务器,客户端是从哪个页面去访问服务器的  (防盗链)。

  User-Agent: 用于告诉服务器,客户端的机器环境(例如所使用的操作系统,浏览器版本号)。

  Cookie:客户端通过这个头字段,可以带一些数据给服务器。

  Connection:客户端通过这个头字段告诉服务器,请求完成后,是保持链接还是关闭链接。

补充:

  UA-CPU:用于告诉服务器,客户端操作系统的平台。

上面的一些消息头中细节说明:

  国际化,比如Google这样的面对全世界的网站,可以根据“Accept-Language”这个消息头来回送对应语言的网页。

  防盗链,一些服务器的资源只允许在某个页面中点击来请求,而不允许别人在他们做的页面中挂个超链接来指向这个资源从而导致在他们网页上直接点击就能获取资源。当然针对这些盗链我们可以指向自己的网站首页进行示威(~~(╯﹏╰)b)

==========================================================================

  现在,来看HTTP协议的响应内容:

  同样,对于服务器端响应客户端的请求,也会将数据进行HTTP协议的封装,形成响应,一个完整的HTTP请求包含了如下内容:一个响应状态行,若干消息头,还有空行之后的实体内容。同请求类似,如下图:

  

  状态行:状态行的开始是使用的HTTP协议版本,后面跟的是状态码,状态码通常可以分为5类,如下:

  

  其中有常见的404(资源未找到),200(请求成功并完成响应),500(服务器出错),剩下的也是非常重要的:

  302:(Move temporarily):服务器告诉客户端其并无所需的资源,要客户端从其他地方寻求(重定向),新的URL在Location响应头中给出。

  307(Temporary Redirect):同302状态码。

  304(Not Modified):指示客户端只需要从缓存中寻求之前获得的数据即可,无需再从服务器端重新请求数据。

  

  常用的响应头也有很多,下图是一个示例:

  

  Location:这个头通常配合302或307状态码使用,服务器使用这个头告诉浏览器去找谁。

  Server:服务器通过这个头告诉浏览器,服务器的类型。

  Content-Encoding: 服务器通过这个头告诉浏览器,数据的压缩格式(gzip)。

  Content-Length:服务器通过这个头告诉浏览器,回送数据的长度。

  Content-Language: 服务器所在系统采用的语言环境。

  Content-Type: 服务器通过这个头告诉浏览器,回送数据的类型(MIME类型);同时也告诉客户端所采用的编码表。

  Last-Modified: 服务器通过这个头告诉浏览器,数据的最后修改时间。

  Refresh:服务器通过这个头告诉浏览器,多长时间定时刷新或定时转向其他页面。

  Content-Disposition: 控制浏览器以下载方式打开回送的数据。

  Transfer-Encoding: 服务器通过这个头告诉浏览器,数据是以块方式回送的。

  ETag:以一个网页或资源来生成某种值,如果网页或资源发生变化,则ETag值也发生变化,用来控制缓存。

  Expires:控制浏览器缓存数据的时间(-1或0,代表控制浏览器不要缓存),如果是具体时间值,则是告诉浏览器在这个时间之前只需去缓存寻取资源即可。

  Cache-Control: no-cache  ,控制浏览器不要缓存该资源

  Pragma: no-cache  ,控制浏览器不要缓存该资源

  (以上三个头一起用,就可以控制所有的浏览器不要缓存数据)

上面的一些响应头中细节说明:

  Content-Type:告诉客户端回送的数据类型,这个数据类型称为MIME类型;同时也告诉客户端所采用的编码表。

  MIME类型根据实际文件的后缀名(即扩展名)来指定数据的样式写法,如为html文件,则对应的MIME类型为:“text/html”,如果是图片jpg文件,则对应的MIME类型为:“image/jpeg”等等。

  各种不同文件对应的MIME类型可以从网上对应,也可以从Tomcat服务器的【conf】目录中的“web.xml”文件中查看。

  Content-Disposition:如果将某个资源设置了这个头,那么这个资源会以下载方式打开,而Content-Disposition头的写法为:“attachment;filename=”+文件URI。

  ETag根据资源的变化做出ETag值的修改,如果客户端访问发现服务器端资源ETag值与客户端缓存中的相同资源ETag值不同,那么客户端就要重新获取数据。其实功能和(请求头If-Modified-Since结合响应头Last-Modified)是相同的,只是ETag能做到毫秒值级别的判断,而后者只能在秒值之间。

为什么控制浏览器不要缓存会有Expires,Cache-Control,Pragma这三个头,这是因为各种浏览器对禁止缓存使用的头不一样,所以以上三个响应头一起使用就可以对付所有浏览器。

最后的补充:

  HTTP请求头中的“Range”请求头,可以请求服务器只传输某个web资源的一部分,这个头可以用来实现断点续传功能(当然前提是服务器是否支持Range功能,通过Accept-Ranges响应头来说明)。Range请求头可以通过三种格式来设置要传输的字节范围:

  ①Range:bytes=1000-2000   (请求传输某个资源1000到2000字节的内容)

  ② Range:bytes=1000-   (请求传输某个资源1000字节以后的内容)

  ③ Range:bytes=1000   (请求传输某个资源最后1000字节的内容)

  而与此对应的则是HTTP响应头中的“Accept-Ranges”响应头,这个响应头说明了该web服务器是否支持Range功能。如果支持则向浏览器返回“Accept-Ranges:bytes”,如果不支持,则返回“Accept-Ranges: none”。

  另外还有一个Content-Range响应头,这个响应头说明了返回该web资源的字节范围,如果服务器支持断点续传功能,那么如果续传成功,则自动返回这个响应头。例:Content-Range:1000-3000/5000

HTTP协议的请求和响应学习的更多相关文章

  1. 老李分享:HTTP协议之请求和响应

    老李分享:HTTP协议之请求和响应   HTTP请求头详解: GET http://www.foo.com/ HTTP/1.1 GET是请求方式,请求方式有GET/POST http://www.fo ...

  2. 【渗透课程】第二篇下-HTTP协议的请求与响应深度剖析

    [渗透课程]第二篇下-HTTP协议的请求与响应深度剖析 HTTP1.1目前支持以下7种请求方法: 常见的MIME类型如下: 第一个数字有五种可能的取值: 目录 什么是请求方法?什么是请求头? HTTP ...

  3. 02_Django-路由配置-HTTP协议的请求和响应

    02_Django-路由配置-HTTP协议的请求和响应 视频:https://www.bilibili.com/video/BV1vK4y1o7jH 博客:https://blog.csdn.net/ ...

  4. 【HTTP】HTTP协议的请求与响应

    创建时间:6.14 http协议 的位置 1.HTTP是什么 超文本传输协议(HyperText Transfer Protocol) 2.Http协议的组成 Http协议由Http请求和Http响应 ...

  5. #WEB安全基础 : HTTP协议 | 0x10 请求和响应报文重点结构及常见头部

    你需要认识一些常见的头部以及了解报文的详细结构 请求报文的请求行 GET/HTTP/1.1 响应报文的响应行 HTTP/1.1 200 OK 想必这些大家都知道了 请求 我访问一个页面 Host // ...

  6. HTTP协议简介详解 HTTP协议发展 原理 请求方法 响应状态码 请求头 请求首部 java模拟浏览器客户端服务端

    协议简介 协议,自然语言里面就是契约,也是双方或者多方经过协商达成的一致意见; 契约也即类似于合同,自然有甲方123...,乙方123...,哪些能做,哪些不能做; 通信协议,也即是双方通过网络通信必 ...

  7. JSP学习之请求和响应编码

    今天的学习涉及到了 jsp中的两大函数 request(请求) 和 response(响应),这应该是大家学习jsp时最先碰到的两个对象,具体有什么作用呢?应该怎么用呢?请继续往下面看. 一.requ ...

  8. http协议(二)请求和响应报文的构成

    http协议用于客户端和服务器之间的通信,请求访问资源的一方称为客户端,而提供资源响应的一方称为服务器端. 下面就是客户端和服务端之间简单的通信过程 PS:请求必须从客户端建立通信,服务端没收到请求之 ...

  9. Django 学习第九天——请求与响应

    一.HttpRequest 对象: 服务器接收到http协议的请求后,会根据报文创建 HttpRequest 对象视图函数的第一个参数是HttpRequest 对象再django.http 模块中定义 ...

随机推荐

  1. c++隐藏实例

    隐藏:是指派生类的函数屏蔽了与其同名的基类函数,规则如下:(1)如果派生类的函数与基类的函数同名,但是参数不同.此时,不论有无virtual关键字,基类的函数将被隐藏(注意别与重载混淆). 很简单略去 ...

  2. android术语笔记

    参考:http://blog.csdn.net/luoshengyang/article/details/6618363 http://blog.csdn.net/singwhatiwanna/art ...

  3. 高性能的JavaScript--加载和执行[转]

    写在前面 JavaScript在浏览器中的性能,可认为是开发者所要面对的最重要的可用性的问题,此问题因JavaScript的阻塞特征而复杂,也就是说JavaScript运行时其他的事情不能被浏览器处理 ...

  4. fancyBox简单入门

    1. 下载 fancyBox,解压后根据需要将文件复制到网页文件夹中(建议不要更改目录结构),并在网页源码中引入相应的 css 样式和 js 文件(如果更改了目录结构,引入的时候请调整相应代码,对应它 ...

  5. commoncrawl 源码库是用于 Hadoop 的自定义 InputFormat 配送实现

    commoncrawl 源码库是用于 Hadoop 的自定义 InputFormat 配送实现. Common Crawl 提供一个示例程序 BasicArcFileReaderSample.java ...

  6. objective-C 初识

    objective-C objective-c 是c语言的改进版 一.方法的定义: 格式: -/+(返回值类型)方法名:(参数类型) 参数名 [方法名] : (参数类型) 参数名......... 例 ...

  7. 一步一步重写 CodeIgniter 框架 (10) —— 使用 CodeIgniter 类库(续)

    上一节简单实现了 CI 的类库扩展模型,所以 _ci_load_class 和 _ci_init_class 写的不是很完备.根据上节课的分析,当 system/libraries 目录下存在 Ema ...

  8. mongoose 数据库操作 - 分页

    使用mongoose 加入分页方法,临时还没发现什么更好的方法,我使用的方法是,直接在源代码中加入 找到 node_modules/mongoose/lib/model.js打开这个文件.里面加入这段 ...

  9. Java 实现享元(Flyweight)模式

    /** * 字母 * @author stone * */ public class Letter { private String name; public Letter(String name) ...

  10. BZOJ 1578: [Usaco2009 Feb]Stock Market 股票市场( 背包dp )

    我们假设每天买完第二天就卖掉( 不卖出也可以看作是卖出后再买入 ), 这样就是变成了一个完全背包问题了, 股票价格为体积, 第二天的股票价格 - 今天股票价格为价值.... 然后就一天一天dp... ...