HTTP 协议详解

最后更新:
阅读次数:

HTTP [wiki] 即超文本传输协议( HyperText Transfer Protocol ),是互联网上应用最为广泛的一种网络协议

  • 1999 年 6 月,定义了 HTTP 协议中现今广泛使用的一个版本—— HTTP 1.1
  • 2015 年 5 月,HTTP/2 标准正式发表,替换 HTTP 1.1 成为 HTTP 的实现标准
  • 设计 HTTP 最初的目的是为了提供一种发布和接收 HTML 页面的方法,但现在它的作用早已不再局限于此。
  • HTTP 是一种 无连接 的协议( 限制每次连接只处理一个请求,后来 Keep-Alive 打破了这种状态 )
    • Keep-Alive 的优势是:避免了每次 HTTP 请求都会造成无谓的 TCP 连接的建立和断开,从而减少了通信量的开销。
    • 并且,在 HTTP/1.1 中,所有的连接默认都是持久连接。
    • 持久连接使得请求在管道中进行发送,这也使得一次并行发送多个请求成为了可能
// 头字段
Connection: Keep - Alive;
  • HTTP 是一种 无状态 的协议( 每个请求都是独立的,服务器不知道每个请求之间的联系 )
    • 所以引入了 Cookie 来记录每次请求的状态
    • 详情: Cookie 会根据从服务器端返回的响应头字段中的一个叫做 Set-Cookie 的字段信息,来通知客户端保存 Cookie。当下次客户端向服务器发送请求时,客户端会自动保存的 Cookie 添加到请求头字段,然后发送给服务器。然后服务器会接收这个 Cookie,然后对比服务器上的记录,最后得到之前的状态信息。

一个完整的 HTTP 请求,通常有以下的 7 个步骤:

  1. 建立 TCP 连接

    • 在 HTTP 开始工作之前,Web 浏览器 主动与 Web 服务器 建立 TCP 连接
  2. Web 浏览器向 Web 服务器发送请求行( A Request line )

    • 例如:POST /ajax-test/text.php HTTP/1.1
  3. Web 浏览器发送请求头信息( Request header fields )

    • 浏览器发送其请求命令之后,还要以头信息的形式向 Web 服务器发送一些别的信息,之后浏览器发送了一空白行来通知服务器,它已经结束了该头信息的发送。 下面是一个请求头信息的例子:
    Host: localhost
    Connection: keep-alive
    Content-Length: 21
    Origin: http://localhost
    User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36
    Content-type: application/x-www-form-urlencoded
    Accept: */*
    Referer: http://localhost/ajax-test/
    Accept-Encoding: gzip, deflate
    Accept-Language: zh-CN,zh;q=0.8
  4. Web 服务器作出应答(A Status line

    • 例如:HTTP/1.1 200 OK
  5. Web 服务器发送应答头信息( Response header fields )

    • 正如客户端会随同请求发送关于自身的信息一样,服务器也会随同应答向用户发送关于它自己的信息,并且也会向客户端发送一个空白行来表示头信息的发送到此为结束。下面是一个应答头信息的例子:
    Date: Sun, 14 Aug 2016 14:28:20 GMT
    Server: Apache/2.4.9 (Win32) PHP/5.5.12
    X-Powered-By: PHP/5.5.12
    Content-Length: 18
    Keep-Alive: timeout=5, max=99
    Connection: Keep-Alive
    Content-Type: text/html
  6. Web 服务器向浏览器发送用户请求的数据

    • 服务器以 Content-Type 应答头信息所描述的格式发送用户所请求的实际数据。
  7. Web 服务器关闭 TCP 连接

    • 一般情况下,一旦 Web 服务器向浏览器发送了请求数据,它就要关闭 TCP 连接,然后如果浏览器或者服务器在其头信息加入了这行代码:Connection:keep-alive TCP 连接在发送后将仍然保持打开状态,于是,浏览器可以继续通过相同的连接发送请求。保持连接节省了为每个请求建立新连接所需的时间,还节约了网络带宽。

一个 HTTP 请求消息的结构(Request Message)

  1. 请求行(A request line)例如: GET /images/logo.gif HTTP/1.1
  2. 请求头字段(Request header fields
    包含一些客户端环境信息,身份验证信息等
  3. 空行(An empty line
    表示头信息结束
  4. 请求体(An optional message body
    请求体中可以包含客户提交的查询字符串信息,表单信息等等

一个 HTTP 响应消息的结构(Response)

  1. 响应行(A status line)例如: HTTP/1.1 200 OK
  2. 响应头字段(Response header fields
    和请求头类似,包含了服务器类型,日期时间,内容类型和长度等信息
  3. 空行(An empty line
    表示头信息结束
  4. 响应体(An optional message body

HTTP 请求方法介绍

HTTP/1.0 支持: GETPOSTHEAD 3 种请求方法。
HTTP/1.1 支持: GETPOSTHEADOPTIONSPUTDELETETRACECONNECT 8 种请求方法。

在浏览网页时,最常见到的请求方法是:GETHEADPOST

GET 请求

  • GET 请求最常用于向服务器请求资源,服务器响应后返回响应内容: 比如向服务器请求一个网页、一张图片等

  • GET 请求也常用于向服务器查询某些信息。

    • 实现方法是:将查询字符串参数追加到 URL 末尾即可(为了确保不会出错,查询字符串需要经过 encodeURIComponent() 进行编码)。
function addURLParam(url, name, value) {
url += url.indexOf("?") == -1 ? "?" : "&";
url += encodeURIComponent(name) + "=" + encodeURIComponent(value);
return url;
}

注意:GET 请求对所发送的信息数量有限制,一般在 2000 个字符左右,并且发送的信息透明,不安全,所以不能用来发送重要信息。

HEAD 请求

HEAD 请求与 GET 请求一样,都是向服务器发出指定资源的请求。但是,服务器在响应 HEAD 请求时不会回传资源的内容部分,即:响应主体。 这样,我们可以在不传输全部内容的情况下,就可以获取服务器的响应头信息。

因此,HEAD 方法常被用于客户端查看服务器的性能、检测 URL 的有效性、获取资源更新的日期时间等。

POST 请求

POST 请求的主要目的不是获取响应的主体内容,而是向服务器发送重要的数据。比如:表单数据提交、文件上传等。

POST 请求把数据作为请求的主体进行提交。并且对发送信息的数量没有限制。安全性也比 GET 请求高。

其它请求

  • PUT 请求: 向指定资源位置上传其最新内容
  • DELETE 请求: 功能与 PUT 请求相反,DELETE 请求请求服务器删除 Request-URI 所标识的资源
  • CONNECT 请求: 该请求要求在与代理服务器通信时建立隧道,实现用隧道协议进行 TCP 通信。通常用于 SSL 加密服务器的链接与非加密的 HTTP 代理服务器的通信。
  • OPTIONS 请求: 该请求使服务器传回 Request-URI 所标识的资源支持的所有 HTTP 请求方法
  • TRACE 请求: 该请求请求服务器回显服务器收到的请求,主要用于测试或诊断

HTTP Headers

HTTP 头字段HTTP Headers) , 指的是在超文本传输协议 (HTTP)的请求和回复消息中,协议头部分的那些组件。它用来准确描述正在获取的资源、服务器或者客户端的行为。

根据实际用途,可以将头字段分为 4 种类型:通用头字段、请求头字段、响应头字段和实体头字段。

  • 常见的 HTTP 通用头字段

    • Cache-Control: 控制缓存的行为
    • Connection: 设置当前连接的类型
    • Date: 创建报文的日期时间
    • Via: 代理服务器的相关信息
    • Transfer-Encoding: 告诉浏览器用来将实体安全地传输给用户的编码形式。当前定义的方法包括:分块 、压缩(compress)、缩小(deflate)、压缩(gzip)、实体(identity)
  • 常见的 HTTP 请求头字段

    • Accept: 用于高速服务器,客户机支持的数据类型
    • Accept-Charset: 用于告诉服务器,客户机采用的编码格式
    • Accept-Encoding: 用于告诉服务器,客户机支持的数据压缩格式
    • Accept-Language: 客户机的语言环境
    • Host: 客户机通过这个头高速服务器,想访问的主机名
    • If-Modified-Since: 客户机通过这个头告诉服务器,资源的缓存时间
    • Referer: 客户机通过这个头告诉服务器,它是从哪个资源来访问服务器的(防盗链)
    • User-Agent: 客户机通过这个头告诉服务器,客户机的软件环境
    • Cookie: 客户机通过这个头可以向服务器带数据
  • 常见的 HTTP 响应头字段

    • Accept-Ranges: 是否接受字节范围请求
    • ETag: 资源的匹配信息
    • Retry-After: 对再次发起请求的时机要求
    • Set-Cookie: 设置 Cookie
    • Server: HTTP 服务器的安装信息
    • Vary: 代理服务器缓存的管理信息
  • 常见的 HTTP 实体头字段

    • Allow: 访问该资源可支持的 HTTP 方法
    • Content-Encoding: 实体的编码方式
    • Content-Length: 实体主体的大小
    • Content-Type: 实体的媒体类型
    • Content-Disposition: 告诉浏览器以下载方式打开数据
    • Expires: 实体主体过期的日期时间
    • Last-Modified: 资源的最后修改日期时间

更详细 HTTP 头字段信息请参看 HTTP 头字段列表 [wiki]

HTTP 状态码

HTTP 状态码(英语:HTTP Status Code)是用以表示网页服务器 HTTP 响应状态的 3 位数字代码。

状态代码的第一个数字代表当前响应的类型:

  • 1xx 消息——接收的请求正在处理
  • 2xx 成功——请求正常处理完毕
  • 3xx 重定向——需要进行附加操作以完成请求
  • 4xx 请求错误——服务器无法处理请求
  • 5xx 服务器错误——服务器处理请求时出错
  • 常见的 HTTP 状态码
    • 200 OK:请求已成功完成,请求所希望的响应头或数据体将随此响应返回。
    • 204 No Content:请求处理成功,但没有资源可返回
    • 206 Partial Content:请求处理成功,服务器将返回指定范围的内容
    • 301 Moved Permanently:永久性重定向。表示请求的资源已经被分配了新的 URI,希望以后对改资源的请求使用新的 URI
    • 302 Found:临时性重定向。表示请求的资源已经被分配了新的 URI,希望本次对改资源的请求使用新的 URI
    • 400 Bad Request:表示请求报文中存在语法错误
    • 403 Forbidden:表明对请求资源的访问被服务器拒绝了
    • 404 Not Found:表明服务器上无法找到请求的资源
    • 408 Request Timeout:请求超时
    • 500 Internal Server Error:表明服务器在执行请求时发生了错误
    • 503 Service Unavailable:表明服务器暂时处于超负荷或正在进行停机维护,现在无法处理请求

更多状态码的详细信息请参看 HTTP 状态码 [wiki]

参考资料