http协议基础


HTTP

[toc]

几个知识

http2已经越来越普及:

二进制编码报文,仍采用TCP,分为若干个帧,来加快传输

HPACK算法压缩大量重复的http头

用服务器推送,即服务端向客户端发送比客户端请求更多的数据。这允许服务器直接提供浏览器渲染页面所需资源,而无须浏览器在收到、解析页面后再提起一轮请求,节约了加载时间

http->SPDY->舍弃->http2.0->http2

HTTPS完全在TLS之上搭载HTTP,因此可以对整个基础HTTP协议进行加密

有大致相同的语法,

MDN Web Docs,以前是Mozilla开发人员网络,以前是Mozilla开发人员中心,是MozillaMicrosoftGoogleSamsung使用的Web开发人员的文档资料库和学习资源。该项目由Mozilla于2005年启动[2],是有关开放式Web标准,Mozilla自己的项目和开发人员指南的统一场所。[3]在2017年,微软,谷歌和三星宣布将关闭自己的文档项目,并将所有文档移至MDN Web Docs。[4]

MDN Web文档的内容由Mozilla和Google的员工和志愿者(开发人员和技术作家的社区)维护。主题包括HTML5JavaScriptCSSWeb APIDjangoNode.jsWebExtensionsMathML等。[5]

TCP是面向连接的,并且可以在发送数据之前在客户端和服务器之间建立连接。建立连接之前,服务器必须正在侦听(被动打开)来自客户端的连接请求。三向握手(主动打开),重传和错误检测可增加可靠性,但会延长等待时间。不需要可靠数据流服务的应用程序可以使用用户数据报协议(UDP),该协议提供无连接 数据报服务,该服务优先考虑时间而不是可靠性。TCP采用避免网络拥塞的方法。但是,TCP存在一些漏洞,包括拒绝服务连接劫持,TCP否决权和重置攻击

握手是在通信电路建立之后,信息传输开始之前。 握手用于达成参数,如信息传输率,字母表,奇偶校验, 中断过程,和其他协议特性。TCP三握手:

第一次握手:建立连接时,客户端发送syn包(syn=j)到服务器,并进入SYN—SEND状态,等待服务器确认;

第二次握手:服务器收到syn包,必须确认客户的SYN(ack=i+j),同时自己也发送一个SYN包(syn=k),即SYN+ACK包,此时服务器进入SYN—RECV状态;

第三次握手:客户端收到服务器的SYN+ACK包.向服务器发送确认包ACK(ack=k+1).此包发送完毕.客户端和服务器进入ESTABI.ISHED状态。完成三次握手。完成三次握手.客户端与服务器开始传送数据 [1]

标识互联网内容

每个资源都由一个 (URI) 来进行标识。

一般情况下,资源的名称和位置由同一个 URL(统一资源定位符,它是 URI 的一种)来标识。也有某些特殊情况,资源的名称和位置由不同的 URI 进行标识:例如,待请求的资源希望客户端从另外一个位置访问它。我们可以使用一个特定的首部字段,Alt-Svc,来指示这种情况。

URI 的最常见形式是统一资源定位符 (URL),它也被称为 Web 地址

https://developer.mozilla.org
https://developer.mozilla.org/en-US/docs/Learn/
https://developer.mozilla.org/en-US/search?q=URL

URN 是另一种形式的 URI,它通过特定命名空间中的唯一名称来标识资源。

urn:isbn:9780141036144
urn:ietf:rfc:7230

URI语法

  1. “://“前是方案或协议

    websocket协议全双工的兼容http的协议

    方案 描述
    data Data URIs
    file 指定主机上文件的名称
    ftp 文件传输协议
    http/https 超文本传输协议/安全的超文本传输协议
    mailto 电子邮件地址
    ssh 安全 shell
    tel 电话
    urn 统一资源名称
    view-source 资源的源代码
    ws/wss (加密的) WebSocket 连接
  2. “//到:之间的域名”

    这既是域名,也代表管理域名的机构,指示了一台主机

  3. ”:xx“是端口

    它表示用于访问 Web 服务器上资源的技术“门”。如果访问的该 Web 服务器使用HTTP协议的标准端口(HTTP为80,HTTPS为443)授予对其资源的访问权限,则通常省略此部分。否则端口就是 URI 必须的部分。

  4. 后面跟着一串路径

  5. 查询字符串

    ?key1=value1&key2=value2 是提供给 Web 服务器的额外参数。这些参数是用 & 符号分隔的键/值对列表。Web 服务器可以在将资源返回给用户之前使用这些参数来执行额外的操作。每个 Web 服务器都有自己的参数规则,想知道特定 Web 服务器如何处理参数的唯一可靠方法是询问该 Web 服务器所有者。

  6. 片段

    #SomewhereInTheDocument 是资源本身的某一部分的一个锚点。锚点代表资源内的一种“书签”,它给予浏览器显示位于该“加书签”点的内容的指示。 例如,在HTML文档上,浏览器将滚动到定义锚点的那个点上;在视频或音频文档上,浏览器将转到锚点代表的那个时间。值得注意的是 # 号后面的部分,也称为片段标识符,永远不会与请求一起发送到服务器。

Data URLs

Data URLs 由四个部分组成:前缀(data:)、指示数据类型的MIME类型、如果非文本则为可选的base64标记、数据本身:

data:[<mediatype>][;base64],<data>
mediatype `是个 MIME 类型的字符串,例如 "`image/jpeg`" 表示 JPEG 图像文件。如果被省略,则默认值为 `text/plain;charset=US-ASCII

有很多问题:

  1. 语法容易出错
  2. html代码若转化成base64可能有问题
  3. 长度限制
  4. 缺乏错误处理
  5. 不支持查询字符串

MIME类型

媒体类型(通常称为 Multipurpose Internet Mail ExtensionsMIME 类型 )是一种标准,用来表示文档、文件或字节流的性质和格式。它在IETF RFC 6838中进行了定义和标准化。

互联网号码分配机构(IANA)是负责跟踪所有官方MIME类型的官方机构,您可以在媒体类型页面中找到最新的完整列表。

重要:浏览器通常使用MIME类型(而不是文件扩展名)来确定如何处理URL,因此Web服务器在响应头中添加正确的MIME类型非常重要。如果配置不正确,浏览器可能会曲解文件内容,网站将无法正常工作,并且下载的文件也会被错误处理。

type/subtype

独立(离散)类型/子类型

  • application在IANA上列出

    没有明确属于其他类型之一的任何类型的二进制数据;或者将以某种方式执行或解释的数据,或者需要特定应用程序或应用程序类别使用的二进制数据。通用二进制数据(或真实类型未知的二进制数据)为application/octet-stream。其他常见的例子包括application/pdfapplication/pkcs8,和application/zip

  • audio在IANA上列出

    音频或音乐数据。例子包括audio/mpegaudio/vorbis

  • example

    保留用作展示如何使用MIME类型的示例中的占位符。这些代码绝对不能在示例代码清单和文档之外使用。 example也可以用作子类型;例如,在一个与在Web上处理音频有关的示例中,MIME类型audio/example可用于指示该类型是占位符,并且在现实世界中使用代码时应使用适当的占位符替换。

  • font在IANA上列出

    字体/字体数据。常见的例子包括font/wofffont/ttf,和font/otf

  • image在IANA上列出

    图像或图形数据,包括位图和矢量静止图像以及静止图像格式的动画版本,例如动画GIF或APNG。常见的例子是image/jpegimage/pngimage/svg+xml

  • model在IANA上列出

    3D对象或场景的模型数据。示例包括model/3mfmodel/vml

  • text在IANA上列出

    纯文本数据,包括任何人类可读的内容,源代码或文本数据,例如逗号分隔值(CSV)格式的数据。实例包括 text/plaintext/csv,和text/html

  • video在IANA上列出

    视频数据或文件,例如MP4电影(video/mp4)。

对于没有特定子类型的文本文档,text/plain应使用。同样,对于没有特定或已知子类型的二进制文件, application/octet-stream应使用。

多部分类型表示文档的分类,通常分为不同的MIME类型。它们也可以用来表示多个独立的文件,尤其是在电子邮件场景中,这些文件都是同一笔交易的一部分。它们代表一个复合文档

除了multipart/form-data用于 HTML FormsPOST方法中的和用于发送文档的一部分外,HTTP不会以特殊方式处理多部分文档:消息会传输到浏览器(可能会显示“另存为”窗口(如果它不知道如何显示文档)。multipart/byteranges206 Partial Content

有两种多部分类型:

  • message在IANA上列出

    包含其他消息的消息。例如,它可以用来表示包含转发的消息作为其数据一部分的电子邮件,或者允许以块的形式发送非常大的消息,就像它是多条消息一样。示例包括message/rfc822(用于转发或回复的消息引用),并 message/partial允许将大消息分解为较小的消息,以便收件人自动进行重组。

  • multipart在IANA上列出

    由多个组件组成的数据,这些组件可能分别具有不同的MIME类型。示例包括multipart/form-data(对于使用FormDataAPI生成的数据)和multipart/byteranges(在RFC 7233:5.4.1中定义 ),并与HTTP206 “部分内容”响应一起使用,当获取的数据仅是内容的一部分(例如使用Range标头传递的内容)时返回)。

常用的*

常见MIME类型列表

很多web服务器使用默认的 application/octet-stream 来发送未知类型。出于一些安全原因,对于这些资源浏览器不允许设置一些自定义默认操作,导致用户必须存储到本地以使用。常见的导致服务器配置错误的文件类型如下所示:

  • RAR编码文件。在这种情况,理想状态是,设置真实的编码文件类型;但这通常不可能(可能是服务器所未知的类型或者这个文件包含许多其他的不同的文件类型)。这这种情况服务器将发送 application/x-rar-compressed 作为MIME类型,用户不会将其定义为有用的默认操作。
  • 音频或视频文件。只有正确设置了MIME类型的文件才能被 ```` 识别和播放。 可参照 use the correct type for audio and video
  • 专有文件类型。是专有文件时需要特别注意。使用 application/octet-stream 作为特殊处理是不被允许的:对于一般的MIME类型浏览器不允许定义默认行为(比如“在Word中打开”)

在缺失 MIME 类型或客户端认为文件设置了错误的 MIME 类型时,浏览器可能会通过查看资源来进行MIME嗅探。每一个浏览器在不同的情况下会执行不同的操作。因为这个操作会有一些安全问题,有的 MIME 类型表示可执行内容而有些是不可执行内容。浏览器可以通过请求头 Content-Type 来设置 X-Content-Type-Options 以阻止MIME嗅探。

MIME类型不是传达文档类型信息的唯一方式:

  • 有时会使用名称后缀,特别是在Microsoft Windows系统上。并非所有的操作系统都认为这些后缀是有意义的(特别是Linux和Mac OS),并且像外部MIME类型一样,不能保证它们是正确的。
  • 魔术数字。不同类型的文件的语法通过查看结构来允许文件类型推断。例如,每个GIF文件以47 49 46 38十六进制值[GIF89]或89 50 4E 47 [.PNG]的PNG文件开头。 并非所有类型的文件都有幻数,所以这也不是100%可靠的方式。

选择www吗

一个服务器不一定是一个独立的物理机:几台服务器可以驻留在同一台物理机器上,或者一台服务器可以通过几台机器进行处理,协作处理并响应或负载均衡它们之间的请求。关键点在于语义上一个域名代表一个单独的服务器

两种设定非官方网站的方法:HTTP301 和<link rel =”canonical”

HTTP概述

![概念图](https://mdn.mozillademos.org/files/13673/HTTP & layers.png)

ps:TLS是传输层安全协议,建立在TCP之上

HTTP被设计于20世纪90年代初期,是一种可扩展的协议。它是应用层的协议,通过TCP,或者是TLS-加密的TCP连接来发送,理论上任何可靠的传输协议都可以使用。因为其良好的扩展性,时至今日,它不仅被用来传输超文本文档,还用来传输图片、视频或者向服务器发送如HTML表单这样的信息。HTTP还可以根据网页需求,仅获取部分Web文档内容更新网页。

实际上,在一个浏览器和处理请求的服务器之间,还有路由器、调制解调器等许多计算机。由于Web的层次设计,那些在网络层和传输层的细节都被隐藏起来了。HTTP位于最上层的应用层。虽然底层对于分析网络问题非常重要,但是大多都跟对HTTP的描述不相干。

server

Server只是虚拟意义上代表一个机器:它可以是共享负载(负载均衡)的一组服务器组成的计算机集群,也可以是一种复杂的软件,通过向其他计算机(如缓存,数据库服务器,电子商务服务器 …)发起请求来获取部分或全部资源。

Server 不一定是一台机器,但一个机器上可以装载的众多Servers。在HTTP/1.1 和Host头部中,它们甚至可以共享同一个IP地址。

代理(Proxies)(这是思科学的东西吧)

在浏览器和服务器之间,有许多计算机和其他设备转发了HTTP消息。由于Web栈层次结构的原因,它们大多都出现在传输层、网络层和物理层上,对于HTTP应用层而言就是透明的,虽然它们可能会对应用层性能有重要影响。还有一部分是表现在应用层上的,被称为代理(Proxies)。代理(Proxies)既可以表现得透明,又可以不透明(“改变请求”会通过它们)。代理主要有如下几种作用:

  • 缓存(可以是公开的也可以是私有的,像浏览器的缓存)
  • 过滤(像反病毒扫描,家长控制…)
  • 负载均衡(让多个服务器服务不同的请求)
  • 认证(对不同资源进行权限管理)
  • 日志记录(允许存储历史信息)

http简单,可扩展,无状态有会话

HTTP 是无状态,有会话的

HTTP是无状态的:在同一个连接中,两个执行成功的请求之间是没有关系的。这就带来了一个问题,用户没有办法在同一个网站中进行连续的交互,比如在一个电商网站里,用户把某个商品加入到购物车,切换一个页面后再次添加了商品,这两次添加商品的请求之间没有关联,浏览器无法知道用户最终选择了哪些商品。而使用HTTP的头部扩展,HTTP Cookies就可以解决这个问题。把Cookies添加到头部中,创建一个会话让每次请求都能共享相同的上下文信息,达成相同的状态。

注意,HTTP本质是无状态的,使用Cookies可以创建有状态的会话。

一个连接是由传输层来控制的,这从根本上不属于HTTP的范围。HTTP并不需要其底层的传输层协议是面向连接的,只需要它是可靠的,或不丢失消息的(至少返回错误),HTTP依赖于面向连接的TCP进行消息传递,但连接并不是必须的。

为了更好的适合HTTP,设计一种更好传输协议的进程一直在进行。Google就研发了一种以UDP为基础,能提供更可靠更高效的传输协议QUIC

HTTP 能控制什么

多年以来,HTTP良好的扩展性使得越来越多的Web功能归其控制。缓存和认证很早就可以由HTTP来控制了。另一方面,对同源同域的限制到2010年才有所改变。

以下是可以被HTTP控制的常见特性。

  • 缓存
    文档如何缓存能通过HTTP来控制。服务端能告诉代理和客户端哪些文档需要被缓存,缓存多久,而客户端也能够命令中间的缓存代理来忽略存储的文档。
  • 开放同源限制
    为了防止网络窥听和其它隐私泄漏,浏览器强制对Web网站做了分割限制。只有来自于相同来源的网页才能够获取网站的全部信息。这样的限制有时反而成了负担,HTTP可以通过修改头部来开放这样的限制,因此Web文档可以是由不同域下的信息拼接成的(某些情况下,这样做还有安全因素考虑)。
  • 认证
    一些页面能够被保护起来,仅让特定的用户进行访问。基本的认证功能可以直接通过HTTP提供,使用Authenticate相似的头部即可,或用HTTP Cookies来设置指定的会话。
  • 代理和隧道
    通常情况下,服务器和/或客户端是处于内网的,对外网隐藏真实 IP 地址。因此 HTTP 请求就要通过代理越过这个网络屏障。但并非所有的代理都是 HTTP 代理。例如,SOCKS协议的代理就运作在更底层,一些像 FTP 这样的协议也能够被它们处理。
  • 会话
    使用HTTP Cookies允许你用一个服务端的状态发起请求,这就创建了会话。虽然基本的HTTP是无状态协议。这很有用,不仅是因为这能应用到像购物车这样的电商业务上,更是因为这使得任何网站都能轻松为用户定制展示内容了。

当HTTP流水线启动时,后续请求都可以不用等待第一个请求的成功响应就被发送。然而HTTP流水线已被证明很难在现有的网络中实现,因为现有网络中有很多老旧的软件与现代版本的软件共存。因此,HTTP流水线已被在有多请求下表现得更稳健的HTTP/2的 帧 所取代。

报文

HTTP/1.1以及更早的HTTP协议报文都是语义可读的。在HTTP/2中,这些报文被嵌入到了一个新的二进制结构,帧。帧允许实现很多优化,比如报文头部的压缩和复用。即使只有原始HTTP报文的一部分以HTTP/2发送出来,每条报文的语义依旧不变,客户端会重组原始HTTP/1.1请求。因此用HTTP/1.1格式来理解HTTP/2报文仍旧有效。

即使HTTP/2为了提高性能将HTTP报文嵌入到帧中这一举措增加了复杂度,但是从Web应用的角度看,报文的基本结构没有变化,从HTTP/1.0发布起就是这样的结构。会话流依旧简单,通过一个简单的 HTTP message monitor就可以查看和纠错。

请求由以下元素组成:

  • 一个HTTP的method,经常是由一个动词像GET, POST 或者一个名词像OPTIONSHEAD来定义客户端的动作行为。通常客户端的操作都是获取资源(GET方法)或者发送HTML form表单值(POST方法),虽然在一些情况下也会有其他操作。
  • 要获取的资源的路径,通常是上下文中就很明显的元素资源的URL,它没有protocolhttp://),domaindeveloper.mozilla.org),或是TCP的port(HTTP一般在80端口)。
  • HTTP协议版本号。
  • 为服务端表达其他信息的可选头部headers
  • 对于一些像POST这样的方法,报文的body就包含了发送的资源,这与响应报文的body类似。

响应报文包含了下面的元素:

  • HTTP协议版本号。
  • 一个状态码(status code),来告知对应请求执行成功或失败,以及失败的原因。
  • 一个状态信息,这个信息是非权威的状态码描述信息,可以由服务端自行设定。
  • HTTP headers,与请求头部类似。
  • 可选项,比起请求报文,响应报文中更常见地包含获取的资源body。

基于HTTP的APIs

基于HTTP的最常用API是XMLHttpRequest API,可用于在user agent和服务器之间交换数据。 现代Fetch API提供相同的功能,具有更强大和灵活的功能集。双工

另一种API,即服务器发送的事件,是一种单向服务,允许服务器使用HTTP作为传输机制向客户端发送事件。 使用EventSource接口,客户端打开连接并建立事件句柄。 客户端浏览器自动将到达HTTP流的消息转换为适当的Event对象,并将它们传递给专门处理这类type事件的句柄,如果有这么个句柄的话。但如果相应的事件处理句柄根本没有建立,那就交给onmessage (en-US)事件处理程序处理

HTTP信息

HTTP消息由采用ASCII编码的多行文本构成。在HTTP/1.1及早期版本中,这些消息通过连接公开地发送。在HTTP/2中,为了优化和性能方面的改进,曾经可人工阅读的消息被分到多个HTTP帧中。

Web 开发人员或网站管理员,很少自己手工创建这些原始的HTTP消息︰ 由软件、浏览器、 代理或服务器完成。他们通过配置文件(用于代理服务器或服务器),API (用于浏览器)或其他接口提供HTTP消息

From a user-, script-, or server- generated event, an HTTP/1.x msg is generated, and if HTTP/2 is in use, it is binary framed into an HTTP/2 stream, then sent.

HTTP/2二进制框架机制被设计为不需要改动任何API或配置文件即可应用︰ 它大体上对用户是透明的。

HTTP 请求和响应具有相似的结构,由以下部分组成︰

  1. 一行起始行用于描述要执行的请求,或者是对应的状态,成功或失败。这个起始行总是单行的。
  2. 一个可选的HTTP头集合指明请求或描述消息正文。
  3. 一个空行指示所有关于请求的元数据已经发送完毕。
  4. 一个可选的包含请求相关数据的正文 (比如HTML表单内容), 或者响应相关的文档。 正文的大小有起始行的HTTP头来指定。

起始行和 HTTP 消息中的HTTP 头统称为请求头,而其有效负载被称为消息正文。

Requests and responses share a common structure in HTTP

HTTP请求详细在这里

HTTP/1.x 报文有一些性能上的缺点:

  • Header 不像 body,它不会被压缩。
  • 两个报文之间的 header 通常非常相似,但它们仍然在连接中重复传输。
  • 无法复用。当在同一个服务器打开几个连接时:TCP 热连接比冷连接更加有效。

HTTP/2 引入了一个额外的步骤:它将 HTTP/1.x 消息分成帧并嵌入到流 (stream) 中。数据帧和报头帧分离,这将允许报头压缩。将多个流组合,这是一个被称为 多路复用 (multiplexing) 的过程,它允许更有效的底层 TCP 连接。

热连接就是活跃的连接,冷连接应该是指新连接的意思。因为 TCP 接连建立需要一定的耗时,还要握手,所以 HTTP 应用保持长连接的话,就可以在多个请求之间复用一个 TCP 连接,这样只需要一次连接和握手,从而大幅度提高资源的加载速度。

从 HTTP1.1 开始,长连接和多路复用就就已经被主流浏览器支持,但是某些网站或者不标准的客户端,还是会在一次请求完成之后关闭连接,变成短连接,从而造成资源的浪费。一般来说,请求头或者响应头字段 Connection: keep-alive 用来告诉另一方自己希望保持连接,并持续复用,直到服务器设定的超时限制达到,或者客户端认为所有资源已经加载完成并主动断开连接。

HTTP2 则在原有长连接和多路复用的基础上,实现了头部压缩和封包发送,以及无序请求-响应模型。HTTP1 的多路复用必须等待前一个请求完成才发送下一个请求,这造成了同步阻塞的问题,而 HTTP2 解决了这个问题,客户端给每一个请求打上序号发给服务器,服务器响应时返回这个序号,客户端就知道这个响应属于那个请求,从而实现了无序异步的多路复用,大大提高了客户端的并发能力并加快了资源的加载。同时 HTTP1 客户端还会在检测当前连接拥塞(被前一个连接长时占用)时开新连接加载其他资源。而HTTP2因为无需等待,则可以永远复用一个连接,减少了连接资源的消耗。–A-yon知乎

HTTP/2 modify the HTTP message to divide them in frames (part of a single stream), allowing for more optimization.

HTTTP/1.x 连接管理

短连接, 长连接, 和 HTTP 流水线。

都有很多问题,还有莫名诡异的域名分片

好像http2中解决了很多很多的问题

自己看吧

https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Connection_management_in_HTTP_1.x

HTTP内容协商

HTTP 协议中,内容协商是这样一种机制,通过为同一 URI 指向的资源提供不同的展现形式,可以使用户代理选择与用户需求相适应的最佳匹配(例如,文档使用的自然语言,图片的格式,或者内容编码形式)。

注意:HTTP内容协商的一些不好的地方在这篇文章中有介绍a wiki page from WHATWG,HTML5提供其他的选择来进行内容协商,如source> element

这个功能好复杂,知道有就好了。。

https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Content_negotiation

HTTP发展

https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Basics_of_HTTP/Evolution_of_HTTP

协议升级

非常方便的,可由服务器端或者客户端发起的协议升级

不要看他下面的中文翻译。。。错得离谱

https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Protocol_upgrade_mechanism

MDN暂时没有

http会话流程

HTTP/2中的帧结构

HTTP/2连接管理

商定http版本


文章作者: Darren
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Darren !
评论
  目录