HTTP详细总结

2018-11-23  本文已影响16人  程序员小逗逼

HTTP详细总结

一、前言

URI

URI(统一资源标识符):我们使用HTTP协议,主要就用来访问互联网上的各种资源,而URI就用来标识这些资源在互联网上的位置,包括两种最常见的方式:URL和URN。
语法:{方案或协议} {主机+端口} {路径} {查询} {锚点}
例如:http://www.example.com:80/path/to/myfile.html?key1=value2&key2=value2#title

协议

协议:http://告诉浏览器采用何种协议,常见的协议有:

协议 描述 作用
data Data URIs
file 本地文件传输协议 访问本地计算机中的文件
ftp 文件传输协议 主要用于远程文件传输
http/https 超文本传输协议/安全的超文本传输协议
mailto 电子邮件协议 用于通知浏览器调用本地邮件客户端发送邮件
ssh 安全外壳协议 提供安全加密的网络传输环境
tel 电话协议 用于通知浏览器调用本地电话客户端发起通话请求
urn 统一资源名称 统一资源名称
view-source 资源源代码 后接资源url可以查看资源源代码
ws/wss WebSocket连接协议 websocket

MIME类型 {#mime}

多用途Internet邮件扩展(MIME)类型 是一种标准化的方式来表示文档的性质和格式。在Windows上我们通常使用文件扩展名来区分使用何种软件来处理文档,而浏览器通常使用MIME类型(而不是文件扩展名)来确定如何处理文档,所以服务器应该在响应对象的头部设置正确的MIME类型。

二、HTTP概览

HTTP协议

HTTP协议(超文本传输协议)是互联网上最广泛的一种网络协议。设计HTTP最初的目的是为了提供一种发布和接收HTML页面的方法。通过HTTP或者HTTPS协议请求的资源由统一资源标识符来标识。

HTTP请求过程

HTTP请求过程

客户端(User-Agent)

一般为用户浏览器。

服务端(Web-Server)

一台或一组能提供Web服务的计算机。

代理(Proxies)

在浏览器和服务器之间有许多机器或设备转发了HTTP消息,这些设备分布于传输层、网络层或者物理层上,而有一些位于应用层,他们就是代理,代理对于客户端和服务器来说既可以是透明的,也可以是可见的。而代理既可能改变HTTP消息,也可能不改变,这就要看代理的具体作用了。各种代理有如下几种作用:

特点

作用

三、HTTP报文

HTTP会话包括客户端发送请求、建立连接、服务端返回响应,建立连接发生在传输层,通常为TCP连接,默认80端口。C-S模型不允许服务器在没有显示发送请求时向客户端发送数据,不过现在开发使用其他技术,如XMLHTTPRequest或Fetch API周期性地请求服务器,以达到类似效果。
客户端发送请求与服务端返回响应分别对应HTTP报文中得请求报文和响应报文。

HTTP请求报文

HTTP请求报文包括请求行、请求头、空行和请求体四部分组成,空行用来隔开请求头与请求体,如下图:

HTTP请求报文

百度首页的请求头如下:

GET / HTTP/1.1
Host: www.baidu.com
Connection: keep-alive
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9
Cookie: BAIDUID=51DCFC83838328932381GS62F770DA7:FG=1;

请求行

请求行由请求的HTTP方法、路径、协议版本三部分组成。
请求方法有:GET、POST、PUT、DELETE、HEAD、CONNECT、OPTIONS、TRACE、PATCH。常用的有GET、POST、PUT、DELETE。

请求头

请求头包含多组由分隔的键值对,用来告诉服务器一些与请求相关的信息。常用头信息后边有写。

请求体

请求体同请求一起发送到服务器端,一般用来更新数据,常用在POST请求,而GET、OPTIONS亲请求一般用来获取数据,不需要发送请求体。
请求体分为两种:

HTTP响应报文

HTTP响应报文包括状态行、响应头、空行和响应报文体四部分组成,空行用来隔开响应头与响应报文体,如下图:

HTTP响应报文

状态行

状态行由协议版本、响应码、响应状态描述组成。

状态码

响应头

响应头与请求头类似,包含多组由分隔的键值对,用来描述服务器的一些相关的信息。

响应报文体

响应报文体即响应的主体,如HTML页面、JPEG图片、PDF文件等等,浏览器会根据响应头中的Content-Type设置的MIME选择相应的处理方式,是该呈现还是下载附件。

常用Header

各Header按照用途可以分为请求头(只用在请求时)、响应头(只用在响应时)、通用头(请求和响应时都可使用)三种。有些可在代码里修改,有些不可修改,由用户代理自行维护,如Date头。

四、Cookie

概述

HTTP Cookie是服务器发送到浏览器并保存在浏览器端的一小块数据,它会在浏览器下次同一服务器时一并发送给服务器。Cookie使无状态的HTTP记录稳定的状态成为了可能。

Cookie作用

使用

创建Cookie

服务器通过在响应头添加Set-Cookie: <cookie名>=<cookie值>来告知浏览器需要保存cookie,当浏览器看到该响应头后就会把其中的cookie键值对保存下来,并在后续的请求中自动添加cookie:<cookie名>=<cookie值>请求头。

访问Cookie

Cookie安全

可以为cookie添加Secure或HttpOnly标记。
添加了Secure标记的cookie只有在https加密时才会发送给服务器以保证cookie不会被截取,如Set-Cookie: id=a3fWa;Secure。尽管如此,还是不建议将敏感信息,如密码,放在cookie中
添加了HttpOnly标记的cookie只在发送HTTP消息时才能被发现,而不能被js抓取到,避免了XSS(跨域脚本攻击)的危害。

Cookie作用域

Domain 和 Path 标识定义了Cookie的作用域:即Cookie应该发送给哪些URL。
Domain标识了哪些主机可以接收cookie,如果不指定,则默认只有当前主机(不包含子域名)可以接收该cookie;如果指定了Domain,则一般包括子域名也可接收。
Path标识了哪些路径(及其子路径)可以接收该cookie。如Set-Cookie: id=a3fWa;path=\docs

五、Cache

Cache概述

常用的缓存有数据库缓存、服务器端缓存、浏览器端缓存等,Cache即浏览器端缓存,当浏览器请求一个web资源后,在浏览器端保存一份该资源的副本,当下次再次请求相同资源时,如果满足特定条件则直接返回该资源的副本,而无需再次发起请求。
合理利用缓存有助于:

  1. 缓解服务器压力
  2. 减少网络带宽
  3. 加快响应速度

Cache三大策略

Cache缓存的工作原理包括三大策略:缓存存储策略、缓存过期策略、缓存验证策略。三大策略分别处理缓存的是否存储、何时过期、验证缓存是否有效。

缓存存储策略

与缓存存储策略相关的有Cache-Control的几个header和Pragma

无法被缓存的情况:

缓存过期策略

与缓存过期策略相关的HTTP头:

缓存过期并不意味着缓存被删除或失效,即使缓存过期了还是有可能使用的。后边的缓存验证策略中会讲到。

缓存验证策略

当缓存的文档过期后,需要进行缓存验证或者重新获取资源。只有在服务器返回强校验器或者弱校验器时才会进行验证

弱校验器:Last-Modified 响应头可以作为一种弱校验器。说它弱是因为它只能精确到一秒。如果响应头里含有这个信息,客户端可以在后续的请求中带上 If-Modified-Since:Last-Modified-valueIf-Unmodified-Since:Last-Modified-value 来验证缓存。

强校验器:ETag可以唯一标识一份资源,可以通过特定计算获得(如md5),如果响应头里含有这个信息,客户端可以在后续的请求中带上 If-Match:ETag-valueIf-None-Match:ETag-value 来验证缓存。尽管ETag比Last-Modified准确很多,但是对ETag的计算会消耗一定的服务器资源或客户端资源。

如图:


缓存策略

访问方式

用户访问方式可以总结为三种:

  1. 直接访问:点击超链接、地址栏输入URL的方式,会进行普通的缓存验证策略。
  2. 刷新页面:点击刷新按钮、F5、右键重新加载,会强制验证缓存,在请求头中加上If-Modified-SinceIf-None-Match,如果满足验证则返回资源,否则返回304来从缓存获取资源。
  3. Ctrl+F5:不采取缓存,强制服务器重新发送完整请求,这时请求头即没有If-Modified-Since也没有If-None-Match

缓存实践

综上对各种HTTP缓存控制头部的对比以及用户可能出现的浏览器刷新行为的讨论,当我们在一个项目上做http缓存的应用时,我们实际上还是会把上述提及的大多数首部字段均使用上。

  1. Expires / Cache-Control
    Expires用时刻来标识失效时间,不免收到时间同步的影响,而Cache-Control使用时间间隔很好的解决了这个问题。 但是 Cache-Control 是 HTTP1.1 才有的,不适用于 HTTP1.0,而 Expires 既适用于 HTTP1.0,也适用于 HTTP1.1,所以说在大多数情况下同时发送这两个头会是一个更好的选择,当客户端两种头都能解析的时候,会优先使用 Cache-Control。
  2. Last-Modified / ETag
    二者都是通过某个标识值来请求资源, 如果服务器端的资源没有变化,则自动返回 HTTP 304 (Not Changed)状态码,内容为空,这样就节省了传输数据量。而当资源发生比那话后,返回和第一次请求时类似。从而保证不向客户端重复发出资源,也保证当服务器有变化时,客户端能够得到最新的资源。
    其中Last-Modified使用文件最后修改作为文件标识值,它无法处理文件一秒内多次修改的情况,而且只要文件修改了哪怕文件实质内容没有修改,也会重新返回资源内容;ETag作为“被请求变量的实体值”,其完全可以解决Last-Modified头部的问题,但是其计算过程需要耗费服务器资源。
  3. from-cache / 304
    Expires和Cache-Control都有一个问题就是服务端作为的修改,如果还在缓存时效里,那么客户端是不会去请求服务端资源的(非刷新),这就存在一个资源版本不符的问题,而强制刷新一定会发起HTTP请求并返回资源内容,无论该内容在这段时间内是否修改过;而Last-Modified和Etag每次请求资源都会发起请求,哪怕是很久都不会有修改的资源,都至少有一次请求响应的消耗。
    对于所有可缓存资源,指定一个Expires或Cache-Control max-age以及一个Last-Modified或ETag至关重要。同时使用前者和后者可以很好的相互适应。
    前者不需要每次都发起一次请求来校验资源时效性,后者保证当资源未出现修改的时候不需要重新发送该资源。而在用户的不同刷新页面行为中,二者的结合也能很好的利用HTTP缓存控制特性,无论是在地址栏输入URI然后输入回车进行访问,还是点击刷新按钮,浏览器都能充分利用缓存内容,避免进行不必要的请求与数据传输。
  4. 避免304
    对于一些css或js等静态文件,不会频繁更新,但每次更新后又需保证客户端能获取到最新,而不是从缓存中获取。可以在url后添加版本号(?md5?version)的方式模拟服务端ETag的原理。而每次更新资源后只需更新其版本号即可,同时为其设置一个较长的Expire或max-age。
上一篇下一篇

猜你喜欢

热点阅读