HTTP内容详解

HTTP是超文本传输协议,用于在web上获取资源的通信协议。它无状态,但通过Cookies实现会话。HTTP依赖TCP,HTTP/1.1引入持久连接和首部,HTTP/2.0采用二进制分帧,支持多路复用。HTTPS基于HTTP,使用TLS加密。HTTP缓存包括强缓存和协商缓存。
摘要由CSDN通过智能技术生成

HTTP

  • HTTP是什么?

    全称: 超文本传输协议(HyperText Transfer Protocol) 。

    概念:HTTP 是一种能够获取像 HTML、图片等网络资源的通讯协议(protocol)。它是在 web 上进行数据交换的基础,是一种 client-server 协议。HTTP 在因特网的角色:充当一个信使的角色,干的就是一个跑腿的活,在客户端和服务端之间传递信息,但我们又不能缺少它。HTTP 协议是应用层的协议,是与前端开发最息息相关的协议。平时我们遇到的 HTTP 请求、 HTTP 缓存、Cookies、跨域等其实都跟 HTTP 息息相关。

  • 基础特性
    • 可拓展协议HTTP 1.0 出现的 HTTP headers 让协议拓展变得更加的容易。只要服务端和客户端就 headers 达成语义一致,新功能就可以被轻松的加入进来
    • HTTP 是无状态的、有会话的。在同一个连接中,两个执行成功的 HTTP 请求之间是没有关系的。这就带来了一个问题,用户没有办法在同一个网站中进行连续的交互,比如在一个电商网站里,用户把某个商品加入到购物车,切换一个页面后再次添加了商品,这两次添加商品的请求之间没有关联,浏览器无法知道用户最终选择了哪些商品。而使用 HTTP 的头部扩展,HTTP Cookies 就可以解决这个问题。把 Cookies 添加到头部中,创建一个会话让每次请求都能共享相同的上下文信息,达成相同的状态
    • HTTP 通过 TCP或者 TLS——加密的 TCP 连接来发送,理论上任何可靠的传输协议都可以使用。连接是传输层控制的,这从根本上来讲不是 HTTP 的范畴。 也就是说,HTTP 依赖于面向连接的 TCP 进行消息传递,但连接并不是必须的。只需要它是可靠的,或不丢失消息的(至少返回错误)

    HTTP/1.0 默认为每一对 HTTP 请求/响应都打开一个单独的 TCP 连接。当需要连续发起多个请求时,这种模式比多个请求共享同一个 TCP 链接更低效。为此,HTTP 1.1 持久连接的概念,底层 TCP 连接可以通过 connection 头部实现。但 HTTP 1.1 在连接上也是不完美的,后面我们会提到。

  • 基于 HTTP 的组件系统

    HTTP 的组件系统包括客户端、web 服务器和代理

    • 客户端:user-agent

      浏览器,特殊比如是工程师使用的程序,以及 Web 开发人员调试应用程序

    • Web服务端

      Web Server 来服务并提供客户端所请求的文档。每一个发送到服务器的请求,都会被服务器处理并返回一个消息,也就是 response

    • 代理(Proxies)

      在浏览器和服务器之间,有很多计算机和其他设备转发了 HTTP 消息。它们可能出现在传输层、网络层和物理层上,对于 HTTP 应用层而言就是透明的。

  • HTTP 报文组成
    • 请求——由客户端发送用来触发一个服务器上的动作
    • 响应——来自服务器端的应答

    HTTP 消息由采用 ASCII 编码的多行文本构成的。在 HTTP/1.1 以及更早的版本中,这些消息通过连接公开的发送。在 HTTP2.0 中,消息被分到了多个 HTTP 帧中。通过配置文件(用于代理服务器或者服务器),API(用于浏览器)或者其他接口提供 HTTP 消息

    • HTTP 请求和响应

      HTTP 请求和响应都包括起始行(start line)、请求头(HTTP Headers)、空行(empty line)以及 body 部分 。

      • 起始行: 请求的起始行:请求方法、请求 PathHTTP 版本号 。
      • 相应行:响应的起始行:HTTP 版本号、响应状态码以及状态文本描述 。

      下面详细说下请求 Path,请求路径(Path)有以下几种:

      1. 一个绝对路径,末尾跟上一个 ’ ? ’ 和查询字符串。这是最常见的形式,称为 原始形式 (origin form),被 GETPOSTHEADOPTIONS 方法所使用 。
      POST / HTTP/1.1
      GET /background.png HTTP/1.0
      HEAD /test.html?query=alibaba HTTP/1.1
      OPTIONS /anypage.html HTTP/1.0
      
      1. 一个完整的 URL。主要在使用 GET 方法连接到代理的时候使用 。
      GET http://developer.mozilla.org/en-US/docs/Web/HTTP/Messages HTTP/1.1
      
      1. 由域名和可选端口(以’:'为前缀)组成的 URLauthority component,称为 authority form。仅在使用 CONNECT 建立 HTTP 隧道时才使用。
      CONNECT developer.mozilla.org:80 HTTP/1.1
      
      1. 星号形式 (asterisk form),一个简单的星号(‘*’),配合 OPTIONS 方法使用,代表整个服务器。
      OPTIONS * HTTP/1.1
      
      • Headers: 请求头或者响应头。详见下面的首部。不区分大小写的字符串,紧跟着的冒号 (‘:’) 和一个结构取决于 header 的值 。

      • 空行。很多人容易忽略

      • Body

        请求 Body 部分:有些请求将数据发送到服务器以便更新数据:常见的的情况是 POST 请求(包含 HTML 表单数据)。请求报文的 Body 一般为两类。一类是通过 Content-TypeContent-Length 定义的单文件 body。另外一类是由多 Body 组成,通常是和 HTML Form 联系在一起的。两者的不同表现在于 Content-Type的值。

      1. Content-Type —— application/x-www-form-urlencoded对于 application/x-www-form-urlencoded 格式的表单内容,有以下特点:
       ​	I.其中的数据会被编码成以&分隔的键值对
      
       ​	II.字符以URL编码方式编码。
      
      1. Content-Type —— multipart/form-data

        请求头中的 Content-Type 字段会包含 boundary,且 boundary 的值有浏览器默认指定。例: Content-Type: multipart/form-data;boundary=----WebkitFormBoundaryRRJKeWfHPGrS4LKe 。 数据会分为多个部分,每两个部分之间通过分隔符来分隔,每部分表述均有 HTTP 头部描述子包体,如Content-Type,在最后的分隔符会加上–表示结束。

       ```js
       Content-Disposition: form-data;name="data1";
       Content-Type: text/plain
       data1
       ----WebkitFormBoundaryRRJKeWfHPGrS4LKe
       Content-Disposition: form-data;name="data2";
       Content-Type: text/plain
       data2
       ----WebkitFormBoundaryRRJKeWfHPGrS4LKe--
       ```
      
  • 方法

    安全方法:HTTP 定义了一组被称为安全方法的方法。GET 方法和 HEAD 方法都被认为是安全的,这意味着 GET 方法和 HEAD 方法都不会产生什么动作 —— HTTP 请求不会再服务端产生什么结果,但这并不意味着什么动作都没发生,其实这更多的是 web 开发者决定的。

    • GET:请求服务器发送某个资源
    • HEAD:跟 GET 方法类似,但服务器在响应中只返回了首部。不会返回实体的主体部分。
    • PUT:向服务器中写入文档。语义:用请求的主体部分来创建一个由所请求的 URL 命名的新文档
    • POST:用来向服务器中输入数据的。通常我们提交表单数据给服务器。【POST 用于向服务器发送数据,PUT 方法用于向服务器上的资源(例如文件)中存储数据】
    • TRACE:主要用于诊断。实现沿通向目标资源的路径的消息环回(loop-back)测试 ,提供了一种实用的 debug 机制。
    • OPTIONS:请求 WEB 服务器告知其支持的各种功能。可以询问服务器支持哪些方法。或者针对某些特殊资源支持哪些方法。
    • DELETE:请求服务器删除请求 URL 中指定的的资源
  • GET 和 POST 的区别

    首先要了解下副作用和幂等的概念,副作用指的是对服务器端资源做修改。幂等指发送 MN 次请求(两者不相同且都大于 1),服务器上资源的状态一致。应用场景上,get是无副作用的,幂等的。post 主要是有副作用的,不幂等的情况。

    技术上有以下的区分:

    • 缓存:Get 请求能缓存,Post 请求不能
    • 安全:Get 请求没有 Post 请求那么安全,因为请求都在 URL 中且会被浏览器保存历史记录。POST 放在请求体中,更加安全
    • 限制:URL 有长度限制,会干预 Get 请求,这个是浏览器决定的
    • 编码:GET 请求只能进行 URL 编码,只能接收 ASCII 字符,而 POST 没有限制。POST 支持更多的编码类型,而且不对数据类型做限制
    • TCP 的角度,GET 请求会把请求报文一次性发出去,而 POST 会分为两个 TCP 数据包,首先发 header 部分,如果服务器响应 100(continue), 然后发 body 部分。(火狐浏览器除外,它的 POST 请求只发一个 TCP 包)
  • 状态码
    • 00~199——信息性状态码

      101 Switching Protocols。在HTTP升级为WebSocket的时候,如果服务器同意变更,就会发送状态码 101。

    • 200~299——成功状态码

      200 OK,表示从客户端发来的请求在服务器端被正确处理

      204 No content,表示请求成功,但响应报文不含实体的主体部分

      205 Reset Content,表示请求成功,但响应报文不含实体的主体部分,但是与 204 响应不同在于要求请求方重置内容

      206 Partial Content,进行范围请求

    • 300~399——重定向状态码

      301 moved permanently,永久性重定向,表示资源已被分配了新的 URL

      302 found,临时性重定向,表示资源临时被分配了新的 URL

      303 see other,表示资源存在着另一个 URL,应使用 GET 方法获取资源

      304 not modified,表示服务器允许访问资源,但因发生请求未满足条件的情况

      307 temporary redirect,临时重定向,和302含义类似,但是期望客户端保持请求方法不变向新的地址发出请求

    • 400~499——客户端错误状态码

      400 bad request,请求报文存在语法错误

      401 unauthorized,表示发送的请求需要有通过 HTTP 认证的认证信息

      403 forbidden,表示对请求资源的访问被服务器拒绝

      404 not found,表示在服务器上没有找到请求的资源

    • 500~599——服务器错误状态码

      500 internal sever error,表示服务器端在执行请求时发生了错误

      501 Not Implemented,表示服务器不支持当前请求所需要的某个功能

      503 service unavailable,表明服务器暂时处于超负载或正在停机维护,无法处理请求

  • 首部 HTTP Headers
    • 通用首部(General headers)同时适用于请求和响应消息,但与最终消息主体中传输的数据无关的消息头。如 Date

    • 请求首部(Request headers)包含更多有关要获取的资源或客户端本身信息的消息头。如 User-Agent

    • 响应首部(Response headers)包含有关响应的补充信息

    • 实体首部(Entity headers)含有关实体主体的更多信息,比如主体长(Content-Length)度或其 MIME 类型。如 Accept-Ranges

  • HTTP 的前世今生
    • HTTP 0.9
      • 单行协议,请求由单行指令构成。以唯一可用的方法 GET 开头。后面跟的是目标资源的路径
      GET /mypage.html
      
      • 响应:只包括响应文档本身
      <HTML>
      这是一个非常简单的HTML页面
      </HTML>
      
      • 没有响应头,只传输 HTML 文件

      • 没有状态码

    • HTTP 1.0
      • 协议版本信息会随着每个请求发送
      • 响应状态码
      • 引入了 HTTP 头的概念,无论是请求还是拓展,允许传输元数据。使协议变得灵活,更加具有拓展性
      • Content-Type 请求头,具备了传输除纯文本 HTML 文件以外其他类型文档的能力 在响应中,Content-Type 标头告诉客户端实际返回的内容的内容类型
      • 虽然 HTTP1.0HTTP 0.9 的基础上改进了很多,但还是存在这不少的缺点。HTTP/1.0 版的主要缺点是,每个 TCP 连接只能发送一个请求。发送数据完毕,连接就关闭,如果还要请求其他资源,就必须再新建一个连接。TCP 连接的新建成本很高,因为需要客户端和服务器三次握手,并且开始时发送速率较慢(slow start
    • HTTP 1.1
      • 连接可以复用。长连接:connection: keep-aliveHTTP 1.1 支持长连接(PersistentConnection),在一个 TCP 连接上可以传送多个 HTTP 请求和响应,减少了建立和关闭连接的消耗和延迟,在 HTTP1.1 中默认开启 Connection:keep-alive,一定程度上弥补了 HTTP1.0 每次请求都要创建连接的缺点。
      • 增加了管道化技术(HTTP Pipelinling),允许在第一个应答被完全发送完成之前就发送第二个请求,以降低通信延迟。复用同一个 TCP 连接期间,即便是通过管道同时发送了多个请求,服务端也是按请求的顺序依次给出响应的;而客户端在未收到之前所发出所有请求的响应之前,将会阻塞后面的请求(排队等待),这称为"队头堵塞"(Head-of-line blocking)。
      • 支持响应分块,分块编码传输:Transfer-Encoding: chunked``Content-length 声明本次响应的数据长度。keep-alive 连接可以先后传送多个响应,因此用 Content-length 来区分数据包是属于哪一个响应。使用 Content-Length 字段的前提条件是,服务器发送响应之前,必须知道响应的数据长度。对于一些很耗时的动态操作来说,这意味着,服务器要等到所有操作完成,才能发送数据,显然这样的效率不高。更好的处理方法是,产生一块数据,就发送一块,采用"流模式"(Stream)取代"缓存模式"(Buffer)。因此,HTTP 1.1 规定可以不使用 Content-Length 字段,而使用"分块传输编码"(Chunked Transfer Encoding)。只要请求或响应的头信息有 Transfer-Encoding: chunked 字段,就表明 body 将可能由数量未定的多个数据块组成。每个数据块之前会有一行包含一个 16 进制数值,表示这个块的长度;最后一个大小为 0 的块,就表示本次响应的数据发送完了。
      • 引入额外的缓存控制机制。HTTP1.0 中主要使用 header 里的 If-Modified-Since,Expires 等来做为缓存判断的标准,HTTP1.1 则引入了更多的缓存控制策略例如 Entity tag, If-None-MatchCache-Control 等更多可供选择的缓存头来控制缓存策略
      • Host 头。不同的域名配置同一个 IP 地址的服务器。HostHTTP 1.1 协议中新增的一个请求头,主要用来实现虚拟主机技术。 虚拟主机(virtual hosting)即共享主机(shared web hosting),可以利用虚拟技术把一台完整的服务器分成若干个主机,因此可以在单一主机上运行多个网站或服务
    • HTTP 2.0
      • 二进制协议。http2.0是一个二进制协议,基本单位是帧,引入了二进制数据帧和流的概念:客户端发送请求时,请求会被分解为多个帧,同一个请求的帧的流标识符相同,每个请求可以理解为一个包含多个帧的流。在二进制分帧层上,http2.0会将所有传输信息分割为帧,并对他们采用二进制格式的编码将其封装。新增的二进制分帧层同时也能保证http的各种动词,方法,首部都不受影响,兼容上一代http标准。
      • 多路复用。新的分帧层机制,http2.0不再依赖多个TCP连接去实现多流并行:每个数据流(请求/相应)都被拆分成很多互不依赖的帧,因为有标识符字段,因此帧可以无序发送(多个请求分解成帧通过一个TCP连接交错发送),最后当帧到达服务器后,根据流标识符来重新组合得到完整的请求。http2.0的TCP连接都是持久化的,而且客户端与服务器之间也只需要一个连接(每个域名一个链接)即可,此连接可以承载数十/数百个流的复用。
      • 压缩了headersHTTP1.xheader 带有大量信息,而且每次都要重复发送,就造成了性能的损耗。为了减少此开销和提升性能,HTTP2.0 使用 HPACK 压缩格式压缩请求和响应标头元数据,这种格式采用两种简单但是强大的技术:这种格式支持通过静态霍夫曼代码对传输的标头字段进行编码,从而减小了各个传输的大小。这种格式要求客户端和服务器同时维护和更新一个包含之前见过的标头字段的索引列表(换句话说,它可以建立一个共享的压缩上下文),此列表随后会用作参考,对之前传输的值进行有效编码。
      • 服务端推送。其允许服务器在客户端缓存中填充数据,通过一个叫服务器推送的机制来提前请求。服务器向客户端推送资源无需客户端明确地请求,服务端可以提前给客户端推送必要的资源,这样可以减少请求延迟时间,例如服务端可以主动把 JSCSS 文件推送给客户端,而不是等到 HTML 解析到资源时发送请求,这样可以减少延迟时间
  • HTTPS
    • HTTPS 也是通过 HTTP 协议进行传输信息,但是采用了 TLS 协议进行了加密。

    • 对称加密和非对称加密
      • 对称加密就是两边拥有相同的秘钥,两边都知道如何将密文加密解密。但是因为传输数据都是走的网络,如果将秘钥通过网络的方式传递的话,一旦秘钥被截获就没有加密的意义的
      • 公钥大家都知道,可以用公钥加密数据。但解密数据必须使用私钥,私钥掌握在颁发公钥的一方。首先服务端将公钥发布出去,那么客户端是知道公钥的。然后客户端创建一个秘钥,并使用公钥加密,发送给服务端。服务端接收到密文以后通过私钥解密出正确的秘钥
    • TLS 握手过程( 非对称加密 )
      • Client Hello: 客户端发送一个随机值(Random1)以及需要的协议和加密方式
      • Server Hello 以及 Certificate: 服务端收到客户端的随机值,自己也产生一个随机值(Random2),并根据客户端需求的协议和加密方式来使用对应的方式,并且发送自己的证书(如果需要验证客户端证书需要说明)
      • Certificate Verify: 客户端收到服务端的证书并验证是否有效,验证通过会再生成一个随机值(Random3),通过服务端证书的公钥去加密这个随机值并发送给服务端,如果服务端需要验证客户端证书的话会附带证书
      • Server 生成 secret: 服务端收到加密过的随机值并使用私钥解密获得第三个随机值(Random3),这时候两端都拥有了三个随机值,可以通过这三个随机值按照之前约定的加密方式生成密钥,接下来的通信就可以通过该密钥来加密解密
  • HTTP 缓存
    • 强缓存: 主要是由 Cache-controlExpires 两个 Header 决定的
      • Expires 的值和头里面的 Date 属性的值来判断是否缓存还有效。ExpiresWeb 服务器响应消息头字段,在响应 http 请求时告诉浏览器在过期时间前浏览器可以直接从浏览器缓存取数据,而无需再次请求。Expires 的一个缺点就是,返回的到期时间是服务器端的时间,这是一个绝对的时间,这样存在一个问题,如果客户端的时间与服务器的时间相差很大(比如时钟不同步,或者跨时区),那么误差就很大。
      • Cache-Control 指明当前资源的有效期,控制浏览器是否直接从浏览器缓存取数据还是重新发请求到服务器取数据。但是其设置的是一个相对时间。

      Cache-control优先级比 Expires优先级高!

    • 协商缓存
      • If-Modified-Since——Last-Modified

      Last-Modified 表示本地文件最后修改日期,浏览器会在 request header 加上 If-Modified-Since(上次返回的 Last-Modified 的值),询问服务器在该日期后资源是否有更新,有更新的话就会将新的资源发送回来

      但是如果在本地打开缓存文件,就会造成 Last-Modified 被修改,所以在 HTTP / 1.1 出现了 ETag

      • If-none-match——ETags

      Etag 就像一个指纹,资源变化都会导致 ETag 变化,跟最后修改时间没有关系,ETag 可以保证每一个资源是唯一的。If-None-Matchheader 会将上次返回的 Etag 发送给服务器,询问该资源的 Etag 是否有更新,有变动就会发送新的资源回来

      If-none-match、ETags 优先级高于 If-Modified-Since、Last-Modified

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值