https://developer.mozilla.org/zh-CN/docs/Web/HTTP
一、定义
是服务器端和客户端之间交换数据的方式
有二种类型的消息:
- 请求:客户端发送一个请求用来触发服务器上的一个动作
- 响应:来自服务器的应答
二、HTTP请求的构成
起始行
Headers
Body
- 请求行/状态行:请求方法,请求网址 协议版本 ——协议版本、响应状态码,状态码描述
- 请求头:键值
- 内容:get请求中通常没有实体,
典型的一个请求行:GET /bell1991/p/7016806.html HTTP/1.1
301:永久重定向--Moved permanently
302:临时重定向---Moved Temporarily
304:没有修改-_Not Modified
401(未授权)-unauthorized:鉴权的接口,某些需要登录才可以访问的接口,没有鉴权就会返回401
500:服务器错误(接口有问题)
502:配置Nginx可能错误
特点
- HTTP 是无状态,有会话的
HTTP是无状态的:在同一个连接中,两个成功执行的请求之间是没有关系的。这就带来了一个问题,用户没办法在一个网站进行连续的交互
比如在一个电商网站里,用户把某个商品加入了购物车中,换了一个页面后再次添加商品,两次添加商品的请求没有联系,浏览器无法知道最终用户都选择了哪些商品。而用HTTP的头部扩展,HTTP Cookies就可以解决这个问题。把Cookies添加到头部中,创建一个会话来让每次请求都能共享相同的上下文信息,相同的状态。
而HTTP的核心是无状态的,cookies的使用可以创建有状态的会话。
- HTTP 和连接
一个连接是由传输层来控制的,基本不属于HTTP的范围内。然而HTTP并不需要下面传输层的协议是面向连接的,它只需要它是可靠的,就是说不能丢失消息(至少没有错误)。在因特网两个最常用的传输层协议中,TCP是可靠的,而UDP不是。因此,HTTP依赖于TCP进行消息传递,虽然TCP是面向连接的,但这并不是必须的。
HTTP/1.0曾经为每一个请求/回应交换都打开一个TCP连接,导致了2个缺点:打开一个连接需要多次的消息往返因此很慢。但是当多个消息周期性的发送时,这就变得更加高效:暖连接比冷连接更高效。为了减少这些负担,HTTP/1.1引入了流水线的概念(已被证明很难实现)和持久连接的概念:下层的TCP连接可以通过Connection头部来被部分地控制。
三、URL-统一资源标识符
描述了特定服务器上特定资源的位置。
1、格式:scheme-方案——所使用的协议类型,一般是HTTP协议
URL-服务器的位置
路径-资源的路径
方案://服务器位置/资源路径
<scheme>://<user>:<pasword>@<host>:<port>/<path>;<params>?<query>#<frag>
方案:协议
用户名和密码:访问每个资源的时候需要的
主机:IP地址
端口:监听的端口
路径:/开始
参数:键值:
查询:?键值&
片段:一部分资源的名称
四、headers
1 Accept(接受的内容类型): text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 2 3 Accept-Encoding(压缩方式): gzip, deflate, sdch, br Accept-Language: zh-CN,zh;q=0.8
4 Accept-Language (页面语言)
5Accept-Charset:(客户端可以处理的字符集类型)
utf-8, iso-8859-1;q=0.5(q=
(q-factor weighting)值代表优先顺序,用相对质量价值 表示,又称为权重。)
6 Content-Length: 3104 消息主体的大小
7Age: 24 在缓存代理中存贮的时长
8 Cache-Control 实现缓存机制
9
Authorization: <type> <credentials> 验证方案 证书
比如:Authorization: Basic YWxhZGRpbjpvcGVuc2VzYW1l
请求消息头含有服务器用于验证用户代理身份的凭证,通常会在服务器返回401
Unauthorized
状态码以及WWW-Authenticate
消息头之后在后续请求中发送此消息头。.
如果使用“基本验证”方案,凭证通过如下步骤生成:
- 用冒号将用户名和密码进行拼接(如:aladdin:opensesame)。
- 将第一步生成的结果用 base64 方式编码(YWxhZGRpbjpvcGVuc2VzYW1l)。
1、基本验证方案
"Basic" HTTP 验证方案是在 RFC 7617中规定的,在该方案中,使用用户的 ID/密码作为凭证信息,并且使用 base64 算法进行编码。这个算法是可逆的,所以不是很安全。
客户端: user-agent
严格意义来说,user-agent就是任何能够表现出用户一般行为的工具。但实际上,这个角色通常都是由浏览器来扮演。简单来说user-agent就是来者何人,留下姓名的意思。对于发起请求来说,浏览器总是作为发起一个请求的实体,而永远不是服务器(虽然一些机制已经能够模拟服务器发起请求的消息了)。要渲染出一个网页,浏览器首先要发送第一个请求来获取这个页面的HTML文档,再解析它并根据文档中的资源信息发送其他的请求来获取脚本信息,或者CSS来进行页面布局渲染,还有一些其它的页面资源(如图片和视频等)。然后,它把这些资源结合到一起,展现出来一个完整的文档,也就是网页。打开一个网页后,浏览器还可以根据脚本内容来获取更多的资源来更新网页。一个网页就是一个超文本文档,也就是说有一部分显示的文本可能是链接,启动它(通常是鼠标的点击)就可以获取一个新的网页。网页使得用户可以控制它的user-agent来导航Web。浏览器来负责翻译HTTP请求的命令,并翻译HTTP的返回消息让用户能明白返回消息的内容。
Connection 头(header) 决定当前的事务完成后,是否会关闭网络连接。如果该值是“keep-alive”,网络连接就是持久的,不会关闭,使得对同一个服务器的请求可以继续在该连接上完成。
Expires
头指定了一个日期/时间, 在这个日期/时间之后,HTTP响应被认为是过时的;如果还有一个 设置了 "max-age" 或者 "s-max-age" 指令的Cache-Control
响应头,那么 Expires
头就会被忽略。
Cache-Control
通用消息头被用于在http 请求和响应中通过指定指令来实现缓存机制。缓存指令是单向的, 这意味着在请求里设置的指令,在响应中不用包含相同的指令。
public
表明响应可以被任何对象(包括:发送请求的客户端,代理服务器,等等)缓存。
private
表明响应只能被单个用户缓存,不能作为共享缓存(即代理服务器不能缓存它)。
no-cache
强制所有缓存了该响应的缓存用户,在使用已存储的缓存数据前,发送带验证器的请求到原始服务器
only-if-cached
表明如果缓存存在,只使用缓存,无论原始服务器数据是否有更新。
Cookie
是一个请求首部,其中含有先前由服务器通过 Set-Cookie
首部投放并存储到客户端的 HTTP cookies。
HTTP Cookie(也叫Web cookie或者浏览器Cookie)是服务器发送到用户浏览器并保存在浏览器上的一块数据,它会在浏览器下一次发起请求时被携带并发送到服务器上。比较经典的,可以它用来确定两次请求是否来自于同一个浏览器,从而能够确认和保持用户的登录状态。Cookie的使用使得基于无状态的HTTP协议上记录稳定的状态信息成为了可能。
由于服务器指定Cookie以后浏览器的每次请求都会携带Cookie数据,这会带来额外的性能负担(尤其是在移动环境下)。新的浏览器API已经允许开发者直接在本地存储数据,如可以使用Web storage API (本地存储和会话存储)和IndexedDB。
当服务器收到HTTP请求时,可以在响应头里面增加一个Set-Cookie
头部。浏览器收到响应之后会取出Cookie信息并保存,之后对该服务器每一次请求中都通过Cookie
请求头部将Cookie信息发送给服务器。另外,Cookie的过期时间、域、路径、有效期、站点都可以根据需要来指定。
Cookie: PHPSESSID=298zf09hf012fh2; csrftoken=u32t4o3tb3gg43; _gat=1;
Cookie主要用在以下三个方面:
- 会话状态管理(如用户登录状态、购物车)
- 个性化设置(如用户自定义设置)
- 浏览器行为跟踪(如跟踪分析用户行为)
HTTP 缓存
重用已经获取的资源能够有效的提升网站与应用的性能。Web 缓存能够减少延迟与网络阻塞,进而减少显示某个资源所用的时间。借助 HTTP 缓存,Web 站点变得更具有响应性。缓存是指存储指定资源的一份拷贝,并在下次请求该资源时提供该拷贝的技术。当 web 缓存发现请求的资源已经被存储,它会拦截请求,返回该资源的拷贝,而不会去源服务器重新下载。这样带来的好处有:缓解服务器端压力,提升性能(获取资源的耗时更短了)。对于网站来说,缓存是达到高性能的重要组成部分。缓存需要合理配置,因为并不是所有资源都是永久不变的:重要的是对一个资源的缓存应截止到其下一次发生改变(即不能缓存过期的资源)
缓存的种类有很多,其大致可归为两类:私有与共享缓存。共享缓存存储的响应能够被多个用户使用。私有缓存只能用于单独用户。除此之外还有网关缓存、CDN、反向代理缓存和负载均衡器等部署在服务器上。虽然 HTTP 缓存不是必须的,但重用缓存的资源通常是必要的。然而常见的 HTTP 缓存只能存储 GET
响应,对于其他类型的响应则无能为力。缓存的关键主要包括request method和目标URI(一般只有GET请求才会被缓存)
缓存控制:
完全不支持缓存:
1 Cache-Control: no-store
2 Cache-Control: no-cache, no-store, must-revalidate
不缓存内容
私有缓存和公共缓存
public:响应可以被任何请求来源缓存。针对需要进行http身份验证的页面或者一些不能被顺利缓存的响应码,通过定义public以支持缓存。
private:响应的内容只能被唯一的用户缓存,不可以被共享缓存存储。隐私模式下的浏览器会通过这种方式存储缓存。
1 Cache-Control: private
2 Cache-Control: public
缓存过期
判断缓存是否过期的一个最常使用的标志是max-age。相对Expires而言,max-age是距离请求发起的时间的秒数。针对应用中那些不会改变的文件,通常可以手动设置一定的时长以保证缓存有效,例如图片、css、js等静态资源。
1 Cache-Control: max-age=31536000
缓存有效性
一旦一个资源文件被存入缓存,理论上来说这个文件就永远处于缓存中。但是缓存的存储空间通常有限,这也意味着定期会移除一部分缓存文件。这个过程称作缓存抛弃。另一方面,针对那些在服务端发生改变的资源,应该做响应的缓存内容更新。因为HTTP协议在C-S架构中是无状态的,服务端在资源发生变化时无法通知到客户端,通过定义过期时间以同步两端的缓存资源。在过期时间前,资源缓存是有效的,反之则缓存失效。通过不停抛弃过期的缓存资源以保证资源的实时性。注意,旧的缓存不会被抛弃或者忽略;当发起一个针对旧缓存资源的请求时,会在请求头里带上If-None-Match用来判断缓存是否还有效。如果有效,服务端返回304(Not Modified)和空的body以节省一部分带宽。
对于含有特定头信息的请求,会去计算缓存寿命。比如Cache-control: max-age=N的请求头,相应的缓存的寿命就是N。通常情况下,对于不含这个属性的请求则会去查看是否包含Expires属性,通过比较Expires的值和头里面Date属性的值来判断是否缓存还有效。如果max-age和expires属性都没有,找找头里的Last-Modified信息。
状态码
400:Bad Request/错误请求
401:未授权,登录失败 Unauthorized表示客户端在授权头信息中没有有效的身份信息时访问受到密码保护的页面。这个响应必须包含一个WWW-Authenticate的授权信息头
403:禁止访问,除非拥有授权否则服务器拒绝提供所请求的资源。这个状态经常会由于服务器上的损坏文件或目录许可而引起。
404-:Not Found/未找到
500 :(Internal Server Error/内部服务器错误)
501 (Not Implemented/未实现)
501 (SC_NOT_IMPLEMENTED)状态告诉客户端服务器不支持请求中要求的功能。例如,客户端执行了如PUT这样的服务器并不支持的命令。
502 (Bad Gateway/错误的网关)
502 (SC_BAD_GATEWAY)被用于充当代理或网关的服务器;该状态指出接收服务器接收到远端服务器的错误响应。
503 (Service Unavailable/服务无法获得)
状态码503 (SC_SERVICE_UNAVAILABLE)表示服务器由于在维护或已经超载而无法响应。例如,如果某些线程或数据库连接池已经没有空闲则servlet会返回这个头信息。服务器可提供一个Retry-After头信息告诉客户端什么时候可以在试一次。
504 (Gateway Timeout/网关超时)
该状态也用于充当代理或网关的服务器;它指出接收服务器没有从远端服务器得到及时的响应。该状态是新加入 HTTP 1.1的。
505 (HTTP Version Not Supported/不支持的 HTTP 版本)
505 (SC_HTTP_VERSION_NOT_SUPPORTED)状态码是说服务器并不支持在请求中所标明 HTTP 版本。该状态是新加入 HTTP 1.1的。