一、什么是 HTTP 协议
Hypertext Transfer Protocol 超文本传输协议,是基于 TCP/IP 协议的应用层协议。默认端口号是 80.
二、特点
- 简单快捷
当客户端向服务器发送请求时,只需传送请求方法和路径。 - 灵活
HTTP 允许传输任意类型的数据对象,由Content-Type
加以标记。 - 无连接
每次连接只处理一个请求。服务器处理完客户端请求,并收到客户端应答后,立即断开连接。节省传输时间。 - 无状态
不对请求和响应之间的状态进行保存。 - 支持 B/S 、 C/S 模式
三、组成
- http 报文是一个格式化的数据块。
- 所有报文分为请求报文和响应报文。
- 请求报文格式
```xml
- 请求报文格式
```xml
- 响应报文格式:
```xml
<version> <status> <reason-phrase>
<headers>
<entity-body>
- http 报文由三个部分组成:
- 对报文进行描述的起始行 Start line
- 包含属性的首部块 Header
- 包含数据的主体部分 Body,可选
- 对报文进行描述的起始行 Start line
1.起始行
请求行
请求报文的起始行。包含了一个方法、一个请求 URL和 http 版本号。字段间由空格分隔。
响应行
响应报文的起始行。包含响应报文使用的 http 版本号、响应状态码和描述状态的原因短语。
方法
HTTP1.0 包含 3 种请求方法:GET、POST、HEAD
HTTP1.1新增 5 种请求方法:OPTIONS、PUT、DELETE、TRACE、CONNECT
- GET
从指定的资源请求数据。一般 GET 方法只用于数据的读取。GET 是不安全的请求方法,因为请求 URL 可以被爬虫任意访问。 - POST
向指定资源提交数据进行处理请求。数据被包含在请求体中。POST 请求可能导致资源被修改或新资源建立。 - HEAD
与 GET 方法类似,向服务器发出指定资源请求。服务器响应 HEAD 请求时不会返回响应主体,只返回响应头信息,一般用于客户端查看服务端的性能。 - OPTIONS
与 HEAD 方法类似,一般也是用于客户端查看服务器的性能。返回服务器支持的 HTTP 方法。JavaScript 的 XMLHttpRequest 对象进行 CORS 跨域请求时,会使用 OPTIONS 方法先发送一个嗅探请求,用来判断是否对指定资源有访问权限。 - PUT
上传内容到指定资源位置。 - DELETE
请求服务器删除所请求 URI 所标识的资源。 - TRACE
回显服务器收到的请求,主要用于测试或诊断。 - CONNECT
HTTP1.1 预留方法,能够将连接改为管道方式的代理服务器。通常用于 SSL 加密服务器的链接与非加密的 HTTP 代理服务器的通信。
状态码
100 ~ 199 信息性状态码
- 100: Continue
说明收到了请求的初始部分,请客户端继续。发送了这个状态码之后,服务器在收到请求之后必须进行响应。 - 101: Switching Protocols
说明服务器正在根据客户端的指定,将协议切换成 Update 首部所列的协议。
- 100: Continue
200 ~ 299 成功状态码
- 200 OK
请求没问题,实体的主体部分包含了所请求的资源。 - 201 Created
用于创建服务器对象的请求,例如 PUT。 - 202 Accepted
请求已被接受,但服务器还未对其执行任何操作。 - 203 Non-Authoritative Information
实体首部包含的信息不是来自于源端服务器,而是来自资源的一份副本。 - 204 No Content
响应报文中包含若干首部和一个状态行,但没有实体的主体部分。例如表单刷新。 - 205 Reset Content
告知浏览器清楚当前页面中的所有 HTML 表单元素。 - 206 Partial Content
成功执行了一个部分或 Range 请求。
- 200 OK
300 ~ 399 重定向状态码
- 300 Multiple Choices
客户端请求一个实际指向多个资源的 URL。 - 301 Moved Permanently
在请求的 URL 已被移除时使用。响应的 Location 首部中应该包含资源现在所处的 URL。永久重定向 - 302 Found
临时重定向,客户端应该使用 Location 首部给出的 URL 来临时定位资源。将来的请求仍用老的 URL - 303 See Other
告知客户端应该用另一个 URL 来获取资源。新的 URL 位于响应报文的 Location 首部。其主要目的是允许 POST 请求的响应将客户端定位到某个资源上去。 - 304 Not Modified
资源未被修改,使用缓存内容。 - 305 Use Proxy
说明必须通过一个代理来访问资源。 - 307 Temporary Redirect
临时重定向,与 302 的区别是 HTTP 版本的区别。
- 300 Multiple Choices
400 ~ 499 客户端错误状态码
- 400 Bad Request
用于告知客户端它发送了一个错误的请求。 - 401 Unauthorized
认证失败,无访问权限。 - 402 Payment Required
- 403 Forbidden
请求被拒绝。 - 404 Not Found
资源不存在。 - 405 Method Not Allowed
不支持所请求的方法。在响应首部的 Allow 中告知客户端可以使用哪些方法。 - 406 Not Acceptable
- 407 Proxy Authentication Required
- 408 Request Timeout
- 409 Conflict
- 410 Gone
- 411 Length Required
- 412 Precondition Failed
- 413 Request Entity Too Large
- 414 Request URI Too Large
- 415 Unsupported Media Type
- 416 Requested Range Not Satisfiable
- 417 Expectation Failed
- 400 Bad Request
500 ~ 599 服务器错误状态码
- 500 Internal Server Error
服务器内部错误 - 501 Not Implemented
请求超出服务器的能力范围 - 502 Bad Gateway
无法连接 - 503 Service Unavailable
服务器暂时无法提供服务 - 504 Gateway Timeout
请求超时 - 505 HTTP Version Not Supported
- 500 Internal Server Error
版本
HTTP/1.0
在 HTTP/0.9 只有 GET 的基础上,增加 POST 和 HEAD 方法,响应内容支持多媒体内容。
请求和响应都增加了版本号、头部信息,响应内容有状态码、引入字符集、授权认证、缓存、内容编码等。
1.0 的缺点是一个连接只能有一次请求,每次请求都要重新建立 TCP 连接,而 TCP 连接的建立需要三次握手,加上慢启动特性,对资源和性能都是一种消耗。
HTTP/1.1
默认情况下所有连接都被保持,即请求头标记了 Connection: keep-alive
,只有当有 Connection: close
标记时,才会被关闭。
持久连接
Connection: Keep-Alive
Keep-Alive: max=5, timeout=120
管道机制
指在一个连接上,客户端发送请求时不需要等待服务端响应后才发送下一个请求,可以连续发几个请求,服务端按照接受请求的顺序依次把响应返回。在响应头部添加Content-Length: 2333
字段,声明本次响应的数据长度(字节),则后面的字节属于下一个请求的响应。分块传输
对于有些数据操作,服务端无法提前知道所返回数据的长度,因此无法使用Content-Length
;为此采用一种分块传输的方式处理响应,即产生一块数据就发送一块数据。在响应头部加入Transfer-Encoding: chunked
表明数据由未定的数据块组成。
1.1虽然可以是持久连接,并引入了管道机制,但其核心还是要按照顺序处理内容,返回响应内容。下一个响应必须等待上一个请求处理完毕,即 对头堵塞 head-of-line blocking
。
优化方法:减少请求;多开持续连接(域名分片)
HTTP/2
二进制协议、多路复用、头信息压缩、推送、请求优先级、安全。
2.首部
首部字段向请求和响应报文添加了一些附加信息。本质上它们是一些名/值对的列表。例如Content-Length: 19
首部分为:
通用首部
既可以出现在请求报文中,也可以出现在响应报文中。Date: ``Tue, 09 Oct 2018 15:32:08 GMT
请求首部
提供更多有关请求的信息。
Accept: text/html,image/apng,*/*
响应首部
提供更多有关响应的信息。Server: nginx
实体首部
描述主体的长度和内容,或者资源本身。Content-type: text/html; charset=utf-8
扩展首部
自定义扩展X-id: xxx
3.主体
实体主体部分是可选的。主体是 HTTP 报文的负荷,即 HTTP 要传输的内容。
四、GET 与 POST 的区别
GET
查询字符串是在 GET 请求的 URL 中发送的:
/path?name1=value1&name2=value2...
- 用于获取资源
- 请求可被缓存
- 请求保留在浏览器历史记录中
- 数据长度受 URL 长度限制,最大 2048 个字符
- 幂等
- 用于获取资源
POST
查询字符串是在 POST 请求的 HTTP 消息主体中发送:
POST URL HTTP/1.1
Host: xxx.com
name1=value1&name2=value2...
- 用于提交数据
- 请求不可缓存
- 请求不会保留在浏览器历史记录中
- 数据长度无限制
- 不幂等
- 用于提交数据
五、持久连接 Keep-Alive
HTTP/1.1 默认开启持久连接 Connection: keep-alive
, 减少建立连接次数,提升性能。
六、Cookie
- Cookie 是指网站为了辨别用户身份、进行 session 跟踪而存储在用户本地客户端的数据。
- 每个 cookie 大小限制 4KB
- cookie 由服务端在响应头部设置
Set-Cookie: name=value;path=/;...
- 删除 cookie 是将过期时间 Expire 设为 0 或 负值,关闭浏览器时会被清除
- 发送请求会自动带上 cookie 信息到服务器,过多 cookie 会增加流量
- 创建 cookie 需要浏览器开启 cookie
- 临时 cookie 在关闭浏览器后被清除,永久 cookie 通过设置过期时间实现
- js 通过
document.cookie
操作
属性
- expires 过期时间
expires = new Date().toGMTString(); - domain 域
domain = xxx.com - path 路径
path = / - secure
标记,在 https 的请求中,包含该标记的 cookie 才会被发到服务器 - HttpOnly
标记 cookie 不能通过 document.cookie 获取
七、内容分发网络 CDN
内容分发网络就是对特定内容进行分发的专门网络。这个网络中的节点可以是 Web 服务器、反向代理或缓存。
八、 HTTPS
https 是在安全的传输层上发送的 http。https 没有将未加密的 http 报文发送给 TCP。它在发送给 TCP 之前,先将其发送给了一个安全层,对其进行加密。
http 安全层是通过 SSL 及其现代代替协议 TLS 来实现的。
九、缓存控制
Expires
在 HTTP/1.0 中,通过 Expires 设置服务端过期时间,在下一次请求时,如果时间小于服务端设置的这个过期时间,则直接使用当前缓存的数据。但该时间是服务端生成,与客户端时间可能不一致,会导致缓存命中的误差。需与 Last-Modified
结合使用
在 1.1 中,使用 Cache-Control
代替
Cache-Control
通用首部,用于通过指令指定缓存机制。值有:
private
: 默认值,客户端可以缓存public
: 客户端和代理服务器都可以缓存max-age: 3600
: 缓存内容将在 3600 秒后失效no-cache
: 需要使用对比缓存来验证缓存数据no-store
: 所有内容都不会被缓存
如果服务器同时设置了 expires 和 cache-control ,则 expires 无效。
对比缓存:判断是否可以使用缓存。当服务器返回 304 时,表示可以继续使用缓存数据。
Last-Modified/If-Modified-Since
当第一次请求一个资源时,服务器返回 200 OK,同时返回一个 Last-Modified
属性标记资源在服务器最后被修改的时间,例如Last-Modified: Wed, 10 Oct 2018 06:45:14 GMT
再次请求该资源时,根据 HTTP 协议规定,客户端向服务器发送 If-Modified-Since
报头,询问在这个时间后资源是否有被修改。若无修改,则服务器返回 304 Not Modified,客户端使用缓存资源。
ETag/If-None-Match
ETag: 被请求变量的实体标记。即服务器响应时给请求的 URL 标记