参考:HTTP 协议入门
HTTP协议
HTTP
是基于 TCP/IP
协议的应用层协议。它不涉及数据包(packet)传输,主要规定了客户端和服务器之间的通信格式,默认使用 80
端口。
发展史
HTTP/0.9
只有一个 GET
命令 ,协议规定,服务器只能回应 HTML
格式的字符串,不能回应别的格式,服务器响应完毕就关闭 TCP
连接。
HTTP/1.0
任何格式的内容都可以发送,进入了 POST
和 HEAD
命令,HTTP
请求和回应的格式改变,每次通信都必须包括头信息。
请求示例:
GET / HTTP/1.0
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5)
Accept: */*
第一行是请求命令,必须在尾部添加协议版本(HTTP/1.0)。后面就是多行头信息,描述客户端的情况。
响应示例:
HTTP/1.0 200 OK
Content-Type: text/plain
Content-Length: 137582
Expires: Thu, 05 Dec 1997 16:00:00 GMT
Last-Modified: Wed, 5 August 1996 15:55:28 GMT
Server: Apache 0.84
<html>
<body>Hello World</body>
</html>
回应的格式是”头信息 + 一个空行(\r\n) + 数据”。其中,第一行是”协议版本 + 状态码(status code) + 状态描述”。
Content-Type 字段
关于字符的编码,1.0 版规定,头信息必须是 ASCII
码,后面的数据可以是任何格式。因此,服务器回应的时候,必须告诉客户端,数据是什么格式,这就是 Content-Type
字段的作用。
常见的 Content-Type
字段的值如下:
text/plain
text/html
text/css
image/jpeg
image/png
image/svg+xml
audio/mp4
video/mp4
application/javascript
application/pdf
application/zip
application/atom+xml
这些数据类型总称为 MIME type
,每个值包括一级类型和二级类型,之间用斜杠分隔。 MIME type
还可以在尾部使用分号,添加参数。
Content-Type: text/html; charset=utf-8
上面的类型表明,发送的是网页,而且编码是 UTF-8
。
客户端请求的时候,可以使用 Accept
字段声明自己可以接受哪些数据格式。
Accept: */*
上面代码中,客户端声明自己可以接受任何格式的数据。
Content-Encoding 字段
由于发送的数据可以是任何格式,因此可以把数据压缩后再发送。 Content-Encoding
字段说明数据的压缩方法。
Content-Encoding: gzip
Content-Encoding: compress
Content-Encoding: deflate
客户端在请求时,用 Accept-Encoding
字段说明自己可以接受哪些压缩方法。
Accept-Encoding: gzip, deflate
缺点
每个
TCP
连接只能发送一个请求。发送数据完毕,连接就关闭,如果还要请求其他资源,就必须再新建一个连接。TCP
连接的新建成本很高,因为需要客户端和服务器三次握手,性能比较差。
为了解决这个问题,有些浏览器在请求时,用了一个非标准的 Connection
字段。
Connection: keep-alive
这个字段要求服务器不要关闭 TCP
连接,以便其他请求复用。服务器同样回应这个字段。
HTTP/1.1
持久连接(persistent connection),即
TCP
连接默认不关闭,可以被多个请求复用,不用声明Connection: keep-alive
。管道机制,在同一个
TCP
连接里面,客户端可以同时发送多个请求。这样就进一步改进了HTTP
协议的效率。
缺点
- 同一个
TCP
连接里面,所有的数据通信是按次序进行的。服务器只有处理完一个回应,才会进行下一个回应。要是前面的回应特别慢,后面就会有许多请求排队等着。
为了避免这个问题,只有两种方法:一是减少请求数,二是同时多开持久连接。
HTTP/2
它不叫 HTTP/2.0,是因为标准委员会不打算再发布子版本了,下一个新版本将是 HTTP/3
。
头信息和数据体都是二进制,并且统称为”帧”(frame):头信息帧和数据帧。
HTTP/2 复用
TCP
连接,在一个连接里,客户端和浏览器都可以同时发送多个请求或回应,而且不用按照顺序一一对应。可以取消某一次请求,同时保证
TCP
连接还打开着,可以被其他请求使用。客户端还可以指定数据流的优先级。优先级越高,服务器就会越早回应。
允许服务器未经请求,主动向客户端发送资源,这叫做服务器推送。
HTTP之URL
HTTP 使用统一资源标识符(Uniform Resource Identifiers, URI)来传输数据和建立连接。 URL
是一种特殊类型的 URI
,包含了用于查找某个资源的足够的信息,格式如下:
http://host[":"port][abs_path]
http
表示要通过 HTTP
协议来定位网络资源; host
表示合法的 Internet 主机域名或者 IP
地址; port
指定一个端口号,为空则使用缺省端口 80
; abs_path
指定请求资源的 URI
;
URI和URL的区别
URI
,是 uniform resource identifier
,统一资源标识符,用来唯一的标识一个资源。 Web
上可用的每种资源如 HTML
文档、图像、视频片段、程序等都是用URI来定位的。
URL
是 uniform resource locator
,统一资源定位器,它是一种具体的 URI
,即 URL
可以用来标识一个资源,而且还指明了如何定位这个资源。
HTTP协议详解之请求
请求行(request line)、请求头部(header)、空行和请求数据四个部分组成。
实例如下:
HTTP协议详解之响应
状态行、消息报头、空行和响应正文四个部分组成。
实例如下:
第一行为状态行,(HTTP/1.1)表明 HTTP
版本为 1.1
版本,状态码为 200
,状态消息为(ok
)。
HTTP协议详解之消息报头篇
普通报头
Cache-Control
用于指定缓存指令,缓存指令是单向的(响应中出现的缓存指令在请求中未必会出现),且是独立的(一个消息的缓存指令不会影响另一个消息处理的缓存机制),HTTP1.0
使用的类似的报头域为Pragma
。
请求时的缓存指令包括:no-cache
(用于指示请求或响应消息不能缓存)、no-store
、max-age
、max-stale
、min-fresh
、only-if-cached
。
响应时的缓存指令包括:public
、private
、no-cache
、no-store
、no-transform
、must-revalidate
、proxy-revalidate
、max-age
、s-maxage
。
Date
表示消息产生的日期和时间。
请求报头
Accept
指定客户端接受哪些类型的信息。
Accept:image/gif,表明客户端希望接受GIF图象格式的资源
Accept:text/html,表明客户端希望接受html文本。
Accept-Charset
用于指定客户端接受的字符集。
Accept-Charset:iso-8859-1,gb2312.utf-8,如果在请求消息中没有设置这个域,缺省是任何字符集都可以接受。
Authorization
用于证明客户端有权查看某个资源。当浏览器访问一个页面时,如果收到服务器的响应代码为 401(未授权),可以发送一个包含 Authorization
请求报头域的请求,要求服务器对其进行验证。
响应报头
Location
用于重定向接收者到一个新的位置,常用在更换域名的时候。
WWW-Authenticate
必须被包含在 401(未授权的)响应消息中,客户端收到 401 响应消息时候,并发送 Authorization
报头域请求服务器对其进行验证时,服务端响应报头就包含该报头域。
实体报头
Last-Modified
用于指示资源的最后修改日期和时间。
HTTP之状态码
状态代码有三位数字组成,第一个数字定义了响应的类别,共分五种类别:
1xx:指示信息–表示请求已接收,继续处理
2xx:成功–表示请求已被成功接收、理解、接受
3xx:重定向–要完成请求必须进行更进一步的操作
4xx:客户端错误–请求有语法错误或请求无法实现
5xx:服务器端错误–服务器未能实现合法的请求
常见状态代码
200 :OK //客户端请求成功
206 :Partial Content 成功执行一个部分请求。这个在用于断点续传时会涉及到。
301 :Moved Permanent 请求的URL被移除了,通常会在
Location
首部中包含新的URL
用于重定向。304 :Not Modified 条件请求进行再验证,资源未改变。
400 :Bad Request //客户端请求有语法错误,不能被服务器所理解
401 :Unauthorized //请求未经授权,这个状态代码必须和 WWW-Authenticate 报头域一起使用
403 :Forbidden //服务器收到请求,但是拒绝提供服务
404 :Not Found //请求资源不存在
500 :Internal Server Error //服务器发生不可预期的错误
503 :Server Unavailable //服务器当前不能处理客户端的请求,一段时间后可能恢复正常
HTTP之请求方法
GET
: 请求指定的页面信息,并返回实体主体。HEAD
: 类似于get
请求,只不过返回的响应中没有具体的内容,用于获取报头POST
: 向指定资源提交数据进行处理请求(例如提交表单或者上传文件),数据被包含在请求体中PUT
: 从客户端向服务器传送的数据取代指定的文档的内容。DELETE
: 请求服务器删除指定的页面。CONNECT
: HTTP/1.1 协议中预留给能够将连接改为管道方式的代理服务器。OPTIONS
: 允许客户端查看服务器的性能。TRACE
: 回显服务器收到的请求,主要用于测试或诊断。
GET和POST请求的区别
GET 请求:
请求的数据会附在
URL
之后(就是把数据放置在HTTP协议头中),以?
分割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。
特定浏览器和服务器对
URL
长度有限制,因此对于GET
请求,传输数据大小就会受到URL
长度的限制。不适合传输大量数据,也不太安全。
POST 请求:
把提交的数据放置在请求正文中,提交的数据不会在地址栏中显示出来,地址栏不会改变。
理论上数据不受限。但实际各个服务器会规定对
post
提交数据大小进行限制,Apache
、IIS6
都有各自的配置。必须将
Content-type
设置为application/x-www-form- urlencoded
。