HTTP协议

参考:HTTP 协议入门

参考:关于HTTP协议,一篇就够了

HTTP协议

HTTP 是基于 TCP/IP 协议的应用层协议。它不涉及数据包(packet)传输,主要规定了客户端和服务器之间的通信格式,默认使用 80 端口。

发展史

HTTP/0.9

只有一个 GET 命令 ,协议规定,服务器只能回应 HTML 格式的字符串,不能回应别的格式,服务器响应完毕就关闭 TCP 连接。

HTTP/1.0

任何格式的内容都可以发送,进入了 POSTHEAD 命令,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 指定一个端口号,为空则使用缺省端口 80abs_path 指定请求资源的 URI

URI和URL的区别

URI,是 uniform resource identifier ,统一资源标识符,用来唯一的标识一个资源。 Web 上可用的每种资源如 HTML 文档、图像、视频片段、程序等都是用URI来定位的。

URLuniform 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-storemax-agemax-stalemin-freshonly-if-cached

响应时的缓存指令包括:publicprivateno-cacheno-storeno-transformmust-revalidateproxy-revalidatemax-ages-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 请求:

  1. 请求的数据会附在 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。

  2. 特定浏览器和服务器对 URL 长度有限制,因此对于 GET 请求,传输数据大小就会受到 URL 长度的限制。

  3. 不适合传输大量数据,也不太安全。

POST 请求:

  1. 把提交的数据放置在请求正文中,提交的数据不会在地址栏中显示出来,地址栏不会改变。

  2. 理论上数据不受限。但实际各个服务器会规定对 post 提交数据大小进行限制,ApacheIIS6 都有各自的配置。

  3. 必须将 Content-type 设置为 application/x-www-form- urlencoded