HTTP有两种报文:请求报文和响应报文
一、请求报文
一个HTTP请求报文由请求行(request line) 、请求头部(header)、空行和请求数据4个部分组成。
下图给出了请求报文的一般格式。
一个简单的例子
POST /user HTTP/1.1 // 请求行
Host: www.user.com
Content-Type: application/x-www-form-urlencoded
Connection: Keep-Alive
User-agent: Mozilla/5.0. // 以上是请求头
(此处必须有一空行 | // 空行分割header和请求内容
name=world // 请求体(可选,如get请求时可选)
1.1 请求行
请求行由三部分组成:请求方法、请求URL(不包括域名 | 、HTTP协议版本
请求方法比较多:GET、POST、HEAD、PUT、DELETE、OPTIONS、TRACE、CONNECT
最常用的是GET和POST。
1.1.1 请求方法
1) GET
传递参数长度受限制,因为传递的参数是直接表示在地址栏中,而特定浏览器和服务器对url的长度是有限制的。
因此,GET不适合用来传递私密数据,也不适合拿来传递大量数据。
一般的HTTP请求大多都是GET。
2)POST
POST把传递的数据封装在HTTP请求数据中,以名称/值的形式出现,可以传输大量数据,对数据量没有限制,也不会显示在URL中。 表单的提交用的是POST。
3)HEAD
HEAD跟GET相似,不过服务端接收到HEAD请求时只返回响应头,不发送响应内容。所以,如果只需要查看某个页面的状态时,用HEAD更高效,因为省去了传输页面内容的时间。
4)DELETE
删除某一个资源。
5)OPTIONS
用于获取当前URL所支持的方法。若请求成功,会在HTTP头中包含一个名为“Allow”的头,值是所支持的方法,如“GET, POST”。
6)PUT
把一个资源存放在指定的位置上。
本质上来讲, PUT和POST极为相似,都是向服务器发送数据,但它们之间有一个重要区别,PUT通常指定了资源的存放位置,而POST则没有,POST的数据存放位置由服务器自己决定。
7)TRACE
回显服务器收到的请求,主要用于测试或诊断。
8)CONNECT
CONNECT方法是HTTP/1.1协议预留的,能够将连接改为管道方式的代理服务器。通常用于SSL加密服务器的链接与非加密的HTTP代理服务器的通信。
1.1.2 HTTP协议版本
1)HTTP/1.0
HTTP/1.0支持:GET、POST、HEAD三种HTTP请求方法。
2)HTTP/1.1
HTTP/1.1是当前正在使用的版本。该版本默认采用持久连接,并能很好地配合代理服务器工作。还支持以管道方式同时发送多个请求,以便降低线路负载,提高传输速度。
HTTP/1.1新增了:OPTIONS、PUT、DELETE、TRACE、CONNECT五种HTTP请求方法。
1.2 请求头部
请求头部由关键字/值对组成,每行一对
典型的请求头有:
● User-Agent:产生请求的浏览器类型;
● Accept:客户端可识别的响应内容类型列表;星号 “ * ” 用于按范围将类型分组,用 “ / ” 指示可接受全部类型,用“ type/* ”指示可接受 type 类型的所有子类型; 比如 Accept:text/xml(application/json)表示希望接受到的是xml(json)类型。
● Accept-Language:客户端可接受的自然语言;
● Accept-Encoding:客户端可接受的编码压缩格式;
● Accept-Charset:可接受的应答的字符集;
● Host:请求的主机名,允许多个域名同处一个IP 地址,即虚拟主机;
● connection:连接方式(close 或 keepalive);
● Cookie:存储于客户端扩展字段,向同一域名的服务端发送属于该域的cookie;
● Content-Type:发送端发送的实体数据的数据类型。 比如,Content-Type:text/html(application/json)表示发送的是html类型。
上图展示一般请求所带有的属性
1.2.1 Content-Type
常见的Content-Type:
| Content-Type | 解释 |
|---|---|
| text/html | html格式 |
| text/plain | 纯文本格式 |
| text/css | CSS格式 |
| text/javascript | js格式 |
| image/gif | gif图片格式 |
| image/jpeg | jpg图片格式 |
| image/png | png图片格式 |
| application/x-www-form-urlencoded | POST专用:普通的表单提交默认是通过这种方式。form表单数据被编码为key/value格式发送到服务器。 |
| application/json | POST专用:用来告诉服务端消息主体是序列化后的 JSON 字符串 |
| text/xml | POST专用:发送xml数据 |
| multipart/form-data | POST专用:下面讲解 |
multipart/form-data用以支持向服务器发送二进制数据,以便可以在 POST 请求中实现文件上传等功能
现在用Postman向百度发送一个请求方式为multipart/form-data的POST包,请求报文是这样的:
POST / HTTP/1.1
Host: www.baidu.com
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW
Cache-Control: no-cache
Postman-Token: 033120fe-2185-15d4-e486-75e86e2baddd
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="url"
https://www.baidu.com/
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="name"
waffle
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="desk"; filename="桌子.jpg"
Content-Type: image/jpeg
...contents of 桌子.jpg...
------WebKitFormBoundary7MA4YWxkTrZu0gW--
其中, boundary这个参数是分界线的意思。
每个参数都由分界线分隔开,参数名(二进制数据还需要指明文件类型)和参数值之间有一行空行,这个空行不能省略:
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="url"
https://www.baidu.com/
消息主体最后以 --boundary-- 标示结束。
更加详细的解释可以参考:Multipart/form-data
1.3 空行
请求头之后是一个空行,通知服务器以下不再有请求头
1.4 请求体
GET没有请求数据,POST有。
与请求数据相关的最常使用的请求头是 Content-Type 和 Content-Length 。
二、响应报文
HTTP响应报文和请求报文的结构差不多,也是由四个部分组成:
2.1、状态行
状态行由三部分组成:服务器HTTP协议版本,响应状态码,状态码的文本描述
格式:HTTP-Version Status-Code Reason-Phrase CRLF
比如:HTTP/1.1 200 OK
2.1.1、状态码:由3位数字组成,第一个数字定义了响应的类别
1xx 消息响应(Informational)
表示请求已被接收,需要继续处理。
- 100 Continue:客户端应继续发送请求的其余部分。
- 101 Switching Protocols:服务器同意切换协议(如从 HTTP/1.1 切换到 WebSocket)。
- 102 Processing:服务器已收到并正在处理请求,但尚未完成。
2xx 成功(Successful)
表示客户端发送的请求已被成功接收、理解和接受。
- 200 OK:请求成功,这是最常见的响应状态。
- 201 Created:请求成功且服务器已创建了新资源(通常用于 POST 或 PUT 请求)。
- 202 Accepted:请求已被接受处理,但尚未处理完成。
- 204 No Content:请求成功,但响应正文中没有内容返回(一般用在只是客户端向服务器发送信息,而服务器不用向客户端返回什么信息的情况。)。
- 206 Partial Content:服务器成功处理了部分 GET 请求(通常用于分片下载或断点续传)。响应报文中包含Content-Range指定范围的实体内容。
3xx 重定向(Redirection)
表示需要客户端采取进一步的操作来完成请求。
- 301 Moved Permanently:请求的资源已被永久移动到新 URL,浏览器后续会自动重定向并缓存。
- 302 Found:请求的资源临时被移动到新 URL(旧称 Temporary Redirect)。
- 303 See Other:指示客户端使用 GET 方法去获取另一个 URL 的资源。
- 304 Not Modified:资源未修改,客户端可以使用本地缓存的内容,无需重新下载。
- 307 Temporary Redirect:临时重定向,要求客户端维持原有的请求方法(如 POST 不能改为 GET)访问新 URL。
- 308 Permanent Redirect:永久重定向,要求客户端维持原有的请求方法访问新 URL。
4xx 客户端错误(Client Error)
表示请求包含语法错误或无法完成请求,通常是客户端原因导致。
- 400 Bad Request:请求语法错误,服务器无法理解(如 JSON 格式错误)。
- 401 Unauthorized:请求未经授权,需要 HTTP 身份验证(如未登录或 Auth Token 无效/缺失)。这个状态代码必须和WWW-Authenticate报头域一起使用。
- 403 Forbidden:服务器理解请求但拒绝执行(如无权限访问该资源)。
- 404 Not Found:服务器找不到请求的资源(URL 拼写错误或资源已删除)。
- 405 Method Not Allowed:请求方法(如 GET、POST、DELETE)不被该资源支持。
- 408 Request Timeout:服务器等待客户端发送请求超时。
- 409 Conflict:请求与服务器当前状态冲突(如注册时用户名已存在)。
- 415 Unsupported media type:不支持的媒体类型
- 429 Too Many Requests:客户端在指定时间内发送了过多请求(触发了限流)。
5xx 服务器错误(Server Error)
表示服务器在处理请求的过程中发生了内部错误。
- 500 Internal Server Error:服务器内部通用错误,通常是代码抛出未捕获的异常。
- 501 Not Implemented:服务器不支持当前请求所需的功能。
- 502 Bad Gateway:充当网关或代理的服务器从上游服务器接收到了无效响应(如 Nginx 找不到 Backend 服务)。
- 503 Service Unavailable:服务器暂时无法处理请求(通常因超载或停机维护)。
- 504 Gateway Timeout:充当网关或代理的服务器未能在规定时间内收到上游服务器的响应(超时)。
一个304的使用场景: 缓存服务器向服务器请求某一个资源的时候,服务器返回的响应报文具有这样的字段:Last-Modified:Wed,7 Sep 2011 09:23:24,缓存器会保存这个资源的同时,保存它的最后修改时间。下次用户向缓存器请求这个资源的时候,缓存器需要确定这个资源是新的,那么它会向原始服务器发送一个HTTP请求(GET方法),并在请求头部中包含了一个字段:If-Modified-Since:Wed,7 Sep 2011 09:23:24,这个值就是上次服务器发送的响应报文中的最后修改时间。
假设这个资源没有被修改,那么服务器返回一个响应报文:
HTTP/1.1 304 Not Modified
Date:Sat, 15 Oct 2011 15:39:29
(空行)
(空响应体)
用304告诉缓存器资源没有被修改,并且响应体是空的,不会浪费带宽。
2.2、响应首部(首部行):位于响应报文状态行之后
Date标头:消息产生的时间
Age标头:(从最初创建开始)响应持续时间
Server标头: 向客户端标明服务器程序名称和版本
ETage标头:不透明验证者
Location标头:URL备用的位置
Content-Length标头:实体的长度
Content-Tyep标头:实体的媒体类型
协商首部: Accept-Ranges: 对当前资源来讲,服务器所能够接受的范围类型 Vary: 首部列表,服务器会根据列表中的内容挑选出最适合的版本发送给客户端 跟安全相关的响应首部: Set-Cookie: 服务器端在某客户端第一次请求时发给令牌 WWW-Authentication: 质询,即要求客户提供帐号和密码
响应首部一般包含如下内容:
2.3、响应实体:位于响应首部(首部行)之后
实体包含了Web客户端请求的对象。Content-Length标头及Content-Type标头用于计算实体的位置、数据类型和数据长度。当Web服务器接收到Web客户端的请求报文后,对HTTP请求报文进行解析,并将Web客户端的请求的对象取出打包,通过HTTP响应报文将数据传回给Web客户端,如果出现错误则返回包含对应错误的错误代码和错误原因的HTTP响应报文。