HTTP
简介
HTTP协议(HyperText Transfer Protocol,超文本传输协议)是因特网上应用最为广泛的一种网络传输协议,所有的WWW文件都必须遵守这个标准。 基于TCP/IP通信协议来传递数据(HTML 文件, 图片文件, 查询结果等)。
工作原理
HTTP协议工作于客户端-服务端架构上。浏览器作为HTTP客户端通过URL向HTTP服务端即WEB服务器发送所有请求。
Web服务器有:Apache服务器,IIS服务器(Internet Information Services)等。
Web服务器根据接收到的请求后,向客户端发送响应信息。
HTTP默认端口号为80
特点
- 无连接:限制每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接。采用这种方式可以节省传输时间。
- 媒体独立:只要客户端和服务器知道如何处理的数据内容,任何类型的数据都可以通过HTTP发送。客户端以及服务器指定使用适合的MIME-type内容类型。
- 无状态:协议对于事务处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大。另一方面,在服务器不需要先前信息时它的应答就较快。
MIME Type
MIME (Multipurpose Internet Mail Extensions) 是描述消息内容类型的因特网标准。
MIME 消息能包含文本、图像、音频、视频以及其他应用程序专用的数据。
MIME Type 是该资源的媒体类型,不是个人指定的,是经过互联网(IETF)组织协商,以 RFC(一系列以编号排定的文件,几乎所有的互联网标准都有收录在其中) 的形式作为建议的标准发布在网上的,大多数的 Web 服务器和用户代理都会支持这个规范 (Email 附件的类型也是通过 MIME Type 指定的)。
媒体类型通常通过 HTTP 协议,由 Web 服务器告知浏览器的,即通过 Content-Type 来表示的。例如:Content-Type:text/HTML。
通常只有一些在互联网上获得广泛应用的格式才会获得一个 MIME Type,如果是某个客户端自己定义的格式,一般只能以 application/x- 开头。
处理本地的文件,在没有人告诉浏览器某个文件的 MIME Type 的情况下,浏览器也会做一些默认的处理,这可能和你在操作系统中给文件配置的 MIME Type 有关。比如在 Windows 下,打开注册表的“HKEY_LOCAL_MACHINESOFTWAREClassesMIMEDatabaseContent Type”主键,你可以看到所有 MIME Type 的配置信息。
常见的MIME类型
- 超文本标记语言文本 .htm,.html text/html
- 普通文本 .txt text/plain
- CSS文件 .css text/css
- GIF图形 .gif image/gif
- JPEG图形 .ipeg,.jpg image/jpeg
- PNG图片 .png image/png
- JSON数据格式 application/json
- XML数据格式 application/xml
- 二进制流数据(如常见的文件下载) application/octet-stream
- PDF文件 .pdf application/pdf
- Word文件 .doc application/msword
- mp3音频文件 .mp3 audio/mpeg
- RTF文本 .rtf application/rtf
- au声音文件 .au audio/basic
- MIDI音乐文件 mid,.midi audio/midi,audio/x-midi
- RealAudio音乐文件 .ra, .ram audio/x-pn-realaudio
- MPEG文件 .mpg,.mpeg video/mpeg
- AVI文件 .avi video/x-msvideo
- GZIP文件 .gz application/x-gzip
- TAR文件 .tar application/x-tar
通信流程

CGI
CGI(Common Gateway Interface) 是 HTTP 服务器与你的或其它机器上的程序进行“交谈”的一种工具,其程序须运行在网络服务器上。 绝大多数的 CGI 程序被用来解释处理来自表单的输入信息,并在服务器产生相应的处理,或将相应的信息反馈给浏览器。CGI 程序使网页具有交互功能。
消息结构
请求报文和响应报文都是由以下4部分组成
- 请求行(request line)/响应行(response line)
格式为:Method Request-URI HTTP-Version 结尾符
结尾符一般用\r\n
- 请求头(request header)/响应头(response header)
通用报头: 既可以出现在请求报头,也可以出现在响应报头中
Date: 表示消息产生的日期和时间
Connection: 允许发送指定连接的选项,例如指定连接是连续的,或者指定“close”选项,通知服务器,在响应完成后,关闭连接
Cache-Control: 用于指定缓存指令,缓存指令是单向的(响应中出现的缓存指令在请求中未必会出现),且是独立的(一个消息的缓存指令不会影响另一个消息处理的缓存机制)(强缓存)
实体报头: 用来定于被传送资源的信息,既可以用于请求也可用于响应。请求和响应消息都可以传送一个实体,常见的实体报头为:
Content-Type: 发送给接收者的实体正文的媒体类型
Content-Lenght: 实体正文的长度
Content-Language: 描述资源所用的自然语言,没有设置则该选项则认为实体内容将提供给所有的语言阅读
Content-Encoding: 实体报头被用作媒体类型的修饰符,它的值指示了已经被应用到实体正文的附加内容的编码,因而要获得Content-Type报头域中所引用的媒体类型,必须采用相应的解码机制。
Last-Modified: 实体报头用于指示资源的最后修改日期和时间(协商缓存)
Expires: 实体报头给出响应过期的日期和时间(强缓存)
请求报头/响应报头
- 空行
http协议规定的格式,一般采用\r\n
- 消息主体(请求数据/响应正文)
一般用于http的post method。通过实体报头规定消息主体的格式内容、
例如 Content-Type:text/plain
该实体报头规定了消息主体的数据是纯文本格式
常见的还有
Content-Type:application/x-www-form-urlencoded,定义为Key=value格式
Content-Type:application/json,定义为序列化为的json字符串
Content-Type:application/x-www-form-urlencoded, <form encType="">中默认的encType,form表单数据被编码为key/value格式发送到服务器(表单默认的提交数据的格式),仅表单键值对
Content-Type:multipart/form-data,定义为表单数据提交
注:multipart/form-data,post的常见提交方式,既可以上传文件等二进制数据,也可以上传表单键值对,只是最后会转化为一条信息;使用该提交方法需要规定一个内容分割符用于分割请求体中的多个post的内容,如文件内容和文本内容自然需要分割开来,不然接收方就无法正常解析和还原这个文件。具体的头信息如下:
Content-Type: multipart/form-data; boundary=${bound}
其中${bound}是自定义的分隔符,一般情况用一长串不会和业务数据重复的字符串表示 ,例如9431149156168
分割符前面需要加上--
最后的分割符后面也需要加上—
所有的数据请求头和数据之间都用\r\n\r\n分开,两个数据间用 --${bound}\r\n分开
例如:
POST /t2/upload.do HTTP/1.1
User-Agent: SOHUWapRebot
Accept-Language: zh-cn,zh;q=0.5
Accept-Charset: GBK,utf-8;q=0.7,*;q=0.7
Connection: keep-alive
Content-Length: 60408
Content-Type:multipart/form-data; boundary=ZnGpDtePMx0KrHh_G0X99Yef9r8JZsRJSXC
Host: w.sohu.com
--ZnGpDtePMx0KrHh_G0X99Yef9r8JZsRJSXC
Content-Disposition: form-data; name="city"
Santa colo
--ZnGpDtePMx0KrHh_G0X99Yef9r8JZsRJSXC
Content-Disposition: form-data;name="desc"
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
...
--ZnGpDtePMx0KrHh_G0X99Yef9r8JZsRJSXC
Content-Disposition: form-data;name="pic"; filename="photo.jpg"
Content-Type: application/octet-stream
Content-Transfer-Encoding: binary
... binary data of the jpg ...
--ZnGpDtePMx0KrHh_G0X99Yef9r8JZsRJSXC--
请求报文结构

请求报头
请求报头通知服务器关于客户端求求的信息,典型的请求头有:
Host: 请求的主机名,允许多个域名同处一个IP地址,即虚拟主机
User-Agent: 发送请求的浏览器类型、操作系统等信息
Accept: 客户端可识别的内容类型列表,用于指定客户端接收那些类型的信息
Accept-Encoding: 客户端可识别的数据编码
Accept-Language: 表示浏览器所支持的语言类型
Connection: 允许客户端和服务器指定与请求/响应连接有关的选项,例如这是为Keep-Alive则表示保持连接。
If-Modified-Since: 客户机通过这个头告诉服务器,资源的缓存时间
Referer: 表明客户机是从哪里来的
Cookie
Transfer-Encoding: 告知接收端为了保证报文的可靠传输,对报文采用了什么编码方式。
请求方法
HTTP1.0 定义了三种请求方法: GET, POST 和 HEAD方法。
HTTP1.1 新增了六种请求方法:OPTIONS、PUT、PATCH、DELETE、TRACE 和 CONNECT 方法。
GET 请求指定的页面信息,并返回实体主体。
HEAD 类似于 GET 请求,只不过返回的响应中没有具体的内容,用于获取报头。
POST 向指定资源提交数据进行处理请求(例如提交表单或者上传文件)。数据被包含在请求体中。POST 请求可能会导致新的资源的建立和/或已有资源的修改。
PUT 从客户端向服务器传送的数据取代指定的文档的内容。
DELETE 请求服务器删除指定的页面。
CONNECT HTTP/1.1 协议中预留给能够将连接改为管道方式的代理服务器。
OPTIONS 允许客户端查看服务器的性能。
TRACE 回显服务器收到的请求,主要用于测试或诊断。
PATCH 是对 PUT 方法的补充,用来对已知资源进行局部更新 。
响应报文结构

响应报头
用于服务器传递自身信息的响应,常见的响应报头:
Location: 用于重定向接受者到一个新的位置,常用在更换域名的时候,表示客户应当到哪里去提取文档。Location通常不是直接设置的,而是通过HttpServletResponse的sendRedirect方法,该方法同时设置状态代码为302。
Server: 包含可服务器用来处理请求的系统信息,与User-Agent请求报头是相对应的
Allow: 服务器支持哪些请求方法(如GET、POST等)
WWW-Authenticate: 客户应该在Authorization头中提供什么类型的授权信息
Set-Cookie 设置和页面关联的Cookie。Servlet不应使用response.setHeader("Set-Cookie", ...),而是应使用HttpServletResponse提供的专用方法addCookie。参见下文有关Cookie设置的讨论。
状态码
HTTP状态码由三个十进制数字组成,第一个十进制数字定义了状态码的类型,后两个数字没有分类的作用。HTTP状态码共分为5种类型:
- 1** 信息,服务器收到请求,需要请求者继续执行操作
- 2** 成功,操作被成功接收并处理
- 3** 重定向,需要进一步的操作以完成请求
- 4** 客户端错误,请求包含语法错误或无法完成请求
- 5** 服务器错误,服务器在处理请求的过程中发生了错误
HTTP1.0
规定浏览器与服务器只保持短暂的连接,浏览器的每次请求都需要与服务器建立一个TCP连接,服务器完成请求处理后立即断开TCP连接,服务器不跟踪每个客户也不记录过去的请求。
- 请求方法只有 GET、HEAD、POST
- 连接无法复用
- head of line blocking(holb),会导致健康的请求会被不健康的请求影响,带宽无法被充分利用,以及后续健康请求被阻塞。而且这种体验的损耗受网络环境影响,出现随机且难以监控。
HTTP1.1
- 支持持久连接(HTTP/1.1的默认模式使用带流水线的持久连接),在一个TCP连接上可以传送多个HTTP请求和响应,减少了建立和关闭连接的消耗和延迟。
- connection头, 如果client使用http1.1协议,但又不希望使用长链接,则需要在header中指明connection的值为close;如果server方也不想支持长链接,则在response中也需要明确说明connection的值为close。不论request还是response的header中包含了值为close的connection,都表明当前正在使用的tcp链接在当天请求处理完毕后会被断掉。以后client再进行新的请求时就必须创建新的tcp链接。
- 浏览器客户端在同一时间,针对同一域名下的请求有一定数量限制。超过限制数目的请求会被阻塞。一些站点会有多个静态资源 CDN 域名的原因之一就是变相的解决浏览器针对同一域名的请求限制阻塞问题。
- 请求方法增加了OPTIONS、PUT、PATCH、DELETE、TRACE 和 CONNECT。
HTTP/1.1相较于 HTTP/1.0 协议的主要区别
1 缓存处理
2 带宽优化及网络连接的使用
3 错误通知的管理
4 消息在网络中的发送
5 互联网地址的维护
6 安全性及完整性
HTTP2.0
- 多路复用 (Multiplexing),允许同时通过单一的 HTTP/2 连接发起多重的请求-响应消息。多流并行而不用依赖建立多个 TCP 连接。
- 二进制分帧,HTTP/2在 应用层(HTTP/2)和传输层(TCP or UDP)之间增加一个二进制分帧层,将所有传输的信息分割为更小的消息和帧(frame),并对它们采用二进制格式的编码。单连接多资源,减少服务端的链接压力,内存占用更少,连接吞吐量更大;而且由于 TCP 连接的减少而使网络拥塞状况得以改善,同时慢启动时间的减少,使拥塞和丢包恢复速度更快。
- 首部压缩(Header Compression),使用 HPACK 算法对首部进行压缩。(SPDY 使用的是通用的DEFLATE 算法)
- 服务端推送(Server Push),服务器可以对客户端的一个请求发送多个响应。