在像 HTTP 这样的客户端-服务器协议中, 会话 由以下三步组成:
- 客户端建立一条 TCP 连接 (如果传输层不是 TCP, 也可以是其他适合的连接).
- 客户端发送请求并等待应答.
- 服务器处理请求并送回应答, 包括一个状态码和对应的数据.
从 HTTP/1.1 开始, 在第三步后连接不再关闭, 客户端可以再次发起新的请求: 第二步和第三步可以进行数次.
建立连接
在客户端-服务器协议中,连接是由客户端发起建立的。HTTP 中打开连接的意思是建立一条下层传输层连接,通常就是 TCP。
使用 TCP 时, HTTP 服务器的默认端口号是 80, 另外还有 8000 和 8080 也很常用。页面的 URL 会包含域名和端口号, 但当后者为 80 时可以省略掉.。前往 Identifying resources on the Web 获取更多细节。
XMLHTTPRequest
或 Fetch
API 周期性地请求服务器, 使用 HTML WebSockets API, 或其他类似的协议.发送客户端请求
一旦连接建立, 用户代理就可以发送请求 (用户代理通常是 web 浏览器, 但也可以是任何其他事物, 例如爬虫). 客户端请求由一系列文本指令组成, 并使用 CRLF 分隔, 它们被划分为三个块:
- 第一行包括请求方法及其参数:
- 文档路径, 即不包括协议和域名的绝对路径 URL
- 使用的 HTTP 协议版本
- 接下来的行每一行都表示一个 HTTP 首部, 为服务器提供关于所需数据的信息 (例如语言, 或 MIME 类型),或是一些改变请求行为的数据 (例如当数据已经被缓存时就不再应答). 这些 HTTP 首部组成一个块, 并以一个空行结束.
- 最后一块是可选的数据块, 包括了更多数据, 这主要被 POST 方法使用.
请求示例
访问 developer.mozilla.org 的根页面,即 http://developer.mozilla.org/,并告诉服务器用户代理倾向于该页面使用法语:
GET / HTTP/1.1 Host: developer.mozilla.org Accept-Language: fr
注意最后的空行,它把首部与数据块分隔开。由于在 HTTP 首部中没有 Content-Length
,数据块是空的,所以服务器可以在收到代表首部结束的空行后就开始处理请求。
例如,发送表单的结果:
POST /contact_form.php HTTP/1.1 Host: developer.mozilla.org Content-Length: 64 Content-Type: application/x-www-form-urlencoded name=Joe%20User&request=Send%20me%20one%20of%20your%20catalogue
请求方法
HTTP 定义了一组 请求方法 用来指定对给定资源的行为. 尽管它们可以是名词, 但这些请求方法有时会 被叫做 HTTP 动词. 最常用的请求方法是 GET
和 POST
:
服务器响应结构
当用户代理发送请求之后, web 服务器会处理它, 并最终送回一个响应. 与客户端请求很类似地, 服务器响应由一系列文本指令组成, 并使用 CRLF 分隔, 但它们被划分为三个不同的块:
- 第一行是 状态行, 包括使用的 HTTP 协议版本, 状态码和一个状态描述 (可读的文本).
- 接下来的行每一行都表示一个 HTTP 首部, 为客户端提供关于所发送数据的一些信息 (如数据大小, 使用的压缩算法, 缓存指示). 与客户端请求的头部块类似, 这些 HTTP 首部组成一个块, 并以一个空行结束.
- 最后一块是数据块, 包括响应的数据 (如果有的话).
响应示例
成功的网页响应:
HTTP/1.1 200 OK Date: Sat, 09 Oct 2010 14:28:02 GMT Server: Apache Last-Modified: Tue, 01 Dec 2009 20:18:22 GMT ETag: "51142bc1-7449-479b075b2891b" Accept-Ranges: bytes Content-Length: 29769 Content-Type: text/html <!DOCTYPE html... (这里是 29769 字节的网页信息)
请求的资源已经永久移动的通知:
HTTP/1.1 301 Moved Permanently Server: Apache/2.2.3 (Red Hat) Content-Type: text/html; charset=iso-8859-1 Date: Sat, 09 Oct 2010 14:30:24 GMT Location: https://developer.mozilla.org/ (该资源的新的链接, 服务器期望用户代理去访问它) Keep-Alive: timeout=15, max=98 Accept-Ranges: bytes Via: Moz-Cache-zlb05 Connection: Keep-Alive X-Cache-Info: caching X-Cache-Info: caching Content-Length: 325 (如果用户代理不能跟随新的链接, 那么就显示一个默认页面) <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN"> <html><head> <title>301 Moved Permanently</title> </head><body> <h1>Moved Permanently</h1> <p>The document has moved <a href="https://developer.mozilla.org/">here</a>.</p> <hr> <address>Apache/2.2.3 (Red Hat) Server at developer.mozilla.org Port 80</address> </body></html>
请求的资源不存在的通知:
HTTP/1.1 404 Not Found Date: Sat, 09 Oct 2010 14:33:02 GMT Server: Apache Last-Modified: Tue, 01 May 2007 14:24:39 GMT ETag: "499fd34e-29ec-42f695ca96761;48fe7523cfcc1" Accept-Ranges: bytes Content-Length: 10732 Content-Type: text/html <!DOCTYPE html... (包含一个站点自定义的页面, 帮助用户找到丢失的资源)
响应状态码
HTTP 响应状态码 用来表示一个 HTTP 请求是否成功完成. 响应被分为 5 种类型: 信息型响应, 成功响应, 重定向, 客户端错误和服务器错误.