http知识体系

641 阅读15分钟

定义

HTTPHyperText Transfer Protocol,超文本传输协议)端与端之间的通讯协议 ,这种协议限制了通讯 💁‍内容的格式 以及各项 💁‍内容的含义

👉网络协议分层

image.png

  • 低三层(了解)
    • 物理层:定义物理设备(硬件设备)如何传输数据
    • 数据链路层:在通信的实体间建立数据链路连接(0,1数据)
    • 网络层:为数据在结点间传输创建逻辑链路
  • 传输层
    • tcp协议在传输层
    • 向用户提供可靠的端到端End-to-End服务
    • 传输层向高层屏蔽了下层数据通信的细节
  • 应用层
    • http协议在应用层
    • 为应用软件提供了很多服务
    • 构建与TCP协议之上
    • 屏蔽网络传输相关细节

👉应用软件架构

  • B/S架构
    • Browser(浏览器) ←→ Server(服务器)
    • 这种软件都是通过浏览器访问一个网站使用, 服务器提供数据存储等服务
  • C/S架构
    • Client(客户端) ←→ Server(服务器)
    • 这种软件通过安装一个软件到电脑,然后使用, 服务器提供数据存储等服务

http历史版本

👉HTTP/0.9

  • 只有一个命令 get
  • 没有header等描述数据的信息
  • 服务器发送完毕,就关闭tcp连接

👉HTTP/1.0(几乎和1.1差不多)

  • 增加了更多命令 post,put,header
  • 增加了状态码(描述服务端处理请求的状态),header(请求数据的描述)等

👉HTTP/1.1(在1.0上增加了功能来优化网络链接的过程)

  • 持久连接/长链接 keep-alive(默认开启)
    • tcp 3次握手连接消耗比较大,延时也会较多
  • pipeline 并行管道化(服务端大多不支持,默认不开启)
  • 增加hosthttp头和其他命令
    • host可以允许一台机器上有几个服务,通过host确定连接哪个

💜 持久连接/http长连接Connection:keep-alive

  • 1.1版本才支持,1.0版本不支持

  • 1.1版本默认打开Connection:Keep-alive

  • Connection

    • Keep-alive
    • close(不开启长连接,每次请求完则关闭这个tcp连接)
  • http协议采用“请求-应答”模式,当使用普通模式,即非Keep-Alive模式时,每个请求/应答客户和客户端和服务器都要新建一个连接,完成之后立即断开连接(http为无连接的协议)

  • 当使用Keep-Alive模式(持久连接,连接重用)时,Keep-Alive功能使客户端到服务器端的连接持续有效,当出现对服务端的后继请求时,Keep-Alive功能避免了重新建立连接

  • 优点:每一次建立连接过程,有TCP三次握手,消耗和延时都比较高

💜 管线化pipeline

  • 管线化原理

    • 在持久连接的情况下,某个连接上的传递类似于请求1->响应1->请求2->响应2->请求3->响应3(整个连接无中断,一次请求对应一次响应)
    • 管线化即在持久连接的基础上消息变成了请求1->请求2->请求3->响应1->响应2->响应3(多次请求打包一次传给服务器,服务器也一次打包全响应回来)
    • 由串行变成了并行
  • 管线化的特点

    • 管线化机制通过持久连接完成,仅HTTP/1.1支持此技术
    • 只有GETHEAD请求可以进行管线化,POST有限制
    • 初次创建连接时不应该启动管线化机制,因为服务器不一定支持HTTP/1.1版本的协议
    • HTTP/1.1要求服务器支持管线化,并不要求服务器对响应进行管线化处理,知识要求管线化请求不失败即可
    • 由于上面提到的服务器端的问题,开启管线化很可能不会带来大幅度的性能提升,而且很多服务器端和代理程序对管线化的支持并不好,因此ChromeFirefox默认并未开启管线化支持

👉HTTP/2.0(为了解决HTTP/1.1性能低下问题,目前还未普及)

  • 二进制传输(之前是字符串)
  • 信道复用,并行传输(类似pipeline
    • 同一连接里发送多个请求不再需要按照顺序来(并发请求),不会阻塞,HTTP/1.1里同一连接里需要第一个发送完才能发送第二个,不能并发。
  • 头信息压缩(减少带宽使用)
  • 推送(之前只有客户端能发起请求,服务端不能主动传输)
    • 例如请求一个html页面,如果里面包含有css,js文件,HTTP/1.1中是需要先请求到页面,再请求里面的css,js,是串行的。而HTTP/2.0是请求页面的同时,服务器将页面包含的css,js等一起推送到客户端
  • 不是所有浏览器都支持HTTP/2.0
    • Nginx可以做兼容,服务器端可以直接用HTTP/1.1Nginx代理服务器可以转换为HTTP/2.0

http协议的主要特点

  • 简单快速
    • 每个资源的URI是固定的,输入该URI就能访问
  • 灵活
    • http协议头部可以设置不同数据类型的传输
  • 无连接
    • 服务器发送完响应,就关闭TCP连接(每次连接后会断掉,不会一直保持连接)
  • 无状态
    • 客户端和服务端建立一次连接后,这个连接会断开,下次再来连接,服务器是无法记住状态的,无法确认

请求响应流程

请求响应流程图👇

image.png

ip 地址用来定位计算机,端口号用来定位具体的应用程序,所有需要联网通信的应用程序都会占用一个端口号(0-65536)

http协议约定形式

  • 🚩 客户端通过随机端口与服务端某固定端口建立连接 三次握手
    • http一般为80https一般为443
  • 🚩 客户端通过这个连接发送请求到服务端(这里的请求是名词)
  • 🚩 服务端监听端口得到的客户端发送过来的请求
  • 🚩 服务端通过连接响应给客户端状态和内容 (响应报文)

http协议约定内容

  • 🚩 请求/响应报文格式
  • 🚩 请求方法➡️GET/POST
  • 🚩 响应状态➡️200/302/304/403/404/500
  • 🚩 预设的请求头/响应头

👉常用状态码含义

定义服务器对请求的处理结果

  • 各个区间的CODE有各自的语义

    💁 1xx: 指示信息

    💁 2xx: 成功,请求已成功接收

    💁 3xx:需要重定向去获取数据

    💁 4xx:客户端错误,请求有语法错误或请求无法实现

    💁 5xx:服务器错误,服务器未能实现合法的请求

  • 详细

    💚 200 OK

    • 客户端请求成功

    💚 206 Partial Content

    • 客户端发送了一个带有Range头的GET请求,服务器完成请求后从文件中截取这个范围内的数据返回(<video><audio>标签请求视频/音频时当文件很大时会出现)

    💚 301 Moved Permanently 永久重定向

    • 浏览器访问一次后,下一次不需要服务器继续指定,浏览器直接会直接从缓存里读取,然后访问'/new'页面。无论服务器怎么改,只要客户端不清缓存,这种修改都是无法成功的

    💚 302 Found

    • 请求的资源临时从不同的 URI 响应请求。后面浏览器每次访问,都会访问服务器,确认跳转到哪里。只有在Cache-Control或 Expires中进行了指定的情况下,这个响应才是可缓存的

    💚 304 Not Modified

    • 没有改变,走缓存
    • 客户端有缓存,服务端告诉客户端可以直接从原来的缓存中取数据。如果客户端发送了一个带条件的 GET 请求且该请求已被允许,而文档的内容(自上次访问以来或者根据请求的条件)并没有改变,则服务器应当返回这个状态码。304 响应禁止包含消息体,因此始终以消息头后的第一个空行结尾

    👿 400 Bad Request

    • 客户端请求有语法错误(参数格式错误等),不能被服务器所理解

    👿 401 Unauthorized

    • 请求未经授权,这个状态代码必须和 WWW-Authenticate 报头域一起使用

    👿 403 Forbidden

    • 资源禁止被访问,服务器已经理解请求,但是拒绝执行它

    👿 404 Not Found

    • 请求失败,请求资源不存在 ,请求所希望得到的资源未被在服务器上发现,可能是输入了错误的URL

    👿 500 Internal Server Error

    • 服务器遇到了一个未曾预料的状况,导致了它无法完成对请求的处理。一般来说,这个问题都会在服务器端的源代码出现错误时出现

    👿 503 Server Unavailable

    • 服务器临时过载或宕机,暂时不能处理客户端的请求,一段时间后可能恢复正常

💜 重定向redirect

response.writeHead(302, {
    'Location': '/new'
})
// 浏览器识别到302,就直接跳转到Location的位置,但是如果返回的code是200,不会跳转
  • 301302的区别
    • 301:浏览器访问一次后,下一次不需要服务器继续指定,浏览器直接会直接从缓存里读取,然后访问/new页面。无论服务器怎么改,只要客户端不清缓存,这种修改都是无法成功的
    • 302:浏览器每次访问,都会访问服务器,确认跳转到哪里

👉http报文组成部分

💜请求报文格式

image.png

🙉 请求行

  • GET /demo.php HTTP/1.1
  • 请求方式+空格+请求路径+空格+HTTP协议版本

🙉 请求头

  • 客户端想要告诉服务端的一些额外信息,键值对形式
  • 常见的如下 键 | 值 | | --------------- | --------------------------- | | Host | 请求的主机 | | Cache-Control | 控制缓存(例如:max-age=60 缓存 60 秒) | | Accept | 客户端想要接收的文档类型,逗号分隔 | | User-Agent | 标识什么客户端帮你发送的这次请求 | | Referer | 这次请求的来源 | | Accept-Encoding | 可以接受的压缩编码 | | Cookie | 客户端本地的小票信息 | | Connection | keep-alive |

🙉 空行

  • 格式而已

🙉 请求体

  • 这次请求客户端想要发送给服务端的数据正文(参数),一般在 GET 请求时很少用到,因为 GET 请求主观上都是去“拿东西”

💜 响应报文格式

image.png

🙉 状态行

  • HTTP/1.1 200 OK
  • HTTP 协议版本 + 空格 + 状态码 + 空格 + 状态描述

🙉 响应头

  • 服务端想要告诉客户端的一些额外信息
Date响应时间
Server服务器信息
Content-Type响应体的内容类型
Content-Length响应的内容大小
Set-Cookie让客户端设置一个小票
Location重定向的地址(302)
Cache-Control设置是否缓存

🙉 空行

  • 仅格式

🙉 响应体

  • 这次请求服务端想要返回给客户端的数据正文,一般返回的都是 HTML,也可以返回 JavaScript 或者 CSS(需要修改响应头中的响应类型)

💜 请求头/响应头参数作用

🙉Content-Type

值为HTTP MIME type,用于指示资源的MIME类型 tool.oschina.net/commons

  1. 纯字符串:text/plain

  2. html:text/html(默认值)

  3. css:text/css

  4. js:application/javascripttext/javascript

  5. json: application/json 请求接口返回的格式

  6. 浏览器的原生form表单:application/x-www-form-urlencoded。提交的数据按照 key1=val1&key2=val2 的方式进行编码,keyval都进行了URL转码

  7. jpg的图:image/jpg图片就不需要指定编码了,因为我们常说的编码一般指的是:字符编码

  8. 上传文件:multipart/form-data。常见的 POST 数据提交的方式。我们使用表单上传文件时,必须让 formenctype 等于这个值。

  9. 让文件下载:application/octet‐stream

    // 当浏览器无法识别该扩展名时,默认会下载下来,除此之外,想要下载,则要做如下处理
    // 让文件下载
    header('Content‐Type: application/octet‐stream');
    // 设置默认下载文件名
    header('Content‐Disposition: attachment; filename=demo.txt');
    
  10. 如果需要设置编码类型,在后面加(;charset=GBK;charset=UTF-8)

🙉 Location

重定向到另一个地址

🙉 Referer

图片防盗链。通过判断请求来源 Referer是否为本网站从而区分是否是合法请求

🙉 数据协商

  • 请求头
    • Accept
    • Accept-Encoding
    • Accept-Language
    • User-Agent
  • 响应头
    • Content-Type 对应 Accept
    • Content-Encoding
    • Content-Language

💜 缓存

🙉 Cache-Control

例子'Cache-Control':'max-age=200, public'

  • 可缓存性

    • public (强制缓存)

      • http请求返回过程中,所经过的所有路径,包括经过的所有代理服务器,和发起请求的浏览器也可以缓存
    • private(强制缓存)

      • 仅发送请求的浏览器可以缓存
    • no-cache(协商缓存)

      • 本地和代理服务器可以存缓存,但是要服务器协商缓存告诉可以使用缓存才能使用
    • no-store(不缓存)

    • 强制缓存的弊端很明显,当缓存过期后,一定会重新去服务器再次请求(不管数据是否有改动),如果数据没有改动,会浪费服务器资源,因此会用到协商缓存

    • 优先级:不缓存 > 强制缓存 > 协商缓存

  • 到期

    • max-age=[seconds] 设置缓存存储的最大周期,超过这个时间缓存被认为过期(单位秒)。与Expires相反,时间是相对于请求的时间。max-age会覆盖掉Expires

    • s-maxage=[seconds],针对代理服务器设置,用于代理缓存。如果存在s-maxage,则会覆盖max-ageExpires

    • max-stale=[seconds],浏览器端设置,即便缓存max-age过期了,还是拿缓存。客户端愿意接收一个已经过期的资源。 可选的设置一个时间(单位秒),表示响应不能超过的过时时间

    • 浏览器端读取max-age,代理服务器如果设置了s-maxage则读取它

  • 重新验证

    • must-revalidate

      • max-age已经过期,必须去原服务端获取数据
    • proxy-revalidate

      • 用在缓存服务器中,过期时,必须去原服务器获取数据
  • 其他

    • no-store

      • 本地和代理服务器都不能存储缓存,禁止缓存
    • no-cache

      • 本地和代理服务器可以存缓存,但是要服务器验证过告诉可以使用缓存才能使用
    • no-transform

      • 不得对资源进行转换或转变。Content-Encoding, Content-Range, Content-Typehttp头不能由代理修改。例如,非透明代理可以对图像格式进行转换,以便节省缓存空间或者减少缓慢链路上的流量。 no-transform指令不允许这样做。

🙉 资源验证,协商缓存(使用no-cache时需要做的)👇

image.png 响应验证头

  • Last-Modified

    • 上次修改时间
    • 配合浏览器请求头If-Modified-Since(推荐)或者If-Unmodified-Since使用
    • 对比上次修改时间验证资源是否需要更新
  • Etag

    • 数据签名,比Last-Modified更严格的验证
    • 配合浏览器请求头If-Match或者If-Non-Match使用
    • 对比资源的签名判断是否使用缓存
  • 如果判断If-MatchEtag相同,或者If-Modified-SinceLast-Modified相同,则会返回304,不再读取服务器的数据,从缓存取数据即可,当设置no-store时,不会在服务端判断,直接重新读取数据,返回200

  • chrome调试工具里面勾选Disable cache

    • 浏览器就不会再发请求头If-MatchIf-Modified-Since了,从而服务端无法判断,无法使用缓存

🙉 expire

  • HTTP/1.0的内容,是强制缓存,过期时间为绝对时间
  • cache-controlexpire同时存在时,cache-control优先级比较高,无论expire是否过期,都无效

🙉 pragma

  • HTTP/1.0的内容,和cache-control类似。前者是http1.0内容后者是http1.1内容
  • pragma优先级 > cache-control优先级,不过前者目前基本不使用

http方法

用来定义对资源的操作,定义上有各自语义

  • get 获取资源
  • post 传输资源
  • put 更新资源
  • delete 删除资源
  • head 获取报文头部

👉POST和GET的区别

1 GET请求会被浏览器主动缓存,而POST不会

2 GET请求参数会被完整保留在浏览器历史记录里,而POST中参数不会被保留

3 GET请求在URL中传送的参数是有长度限制的,而POST没有限制

4 GET比POST更不安全,因为参数直接暴露在URL上,所以不能用来传递敏感信息

0GETPOST
浏览器后退无害请求会被重新提交
url地址收藏为书签可以不可以
浏览器缓存主动缓存不主动缓存,除非手动设置
编码类型只支持url编码:application/x-www-form-urlencoded支持多种编码方式
浏览器历史记录参数保存在浏览器历史记录中参数不保留(可防止CRS攻击)
参数长度限制GET 方法向 URL 添加数据;URL 的长度是受限制的(URL 的最大长度是 2048 个字符(2kb)),太长会被截断无限制
参数数据类型限制只接受ASCII字符无限制
安全性与 POST 相比,GET 的安全性较差,因为所发送的数据是 URL 的一部分。在发送密码或其他敏感信息时绝不要使用 GETPOST 比 GET 更安全,因为参数不会被保存在浏览器历史或 web 服务器日志中
参数可见性url传递,所有人可见Request body中,url中看不见

http与https的区别

  • http是明文传输
    • 传输过程中的包被截取后,信息完全泄露
  • https是靠谱的加密传输
    • 私钥:服务器的私钥解密
    • 公钥:互联网上传输的公钥,需要服务器上的私钥来解密
    • 实际传输数据只有客户端和服务端通过主密钥来获取到

Cookie与Session

后续补充