HTTP | 青训营笔记

126 阅读17分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 16 天

HTTP学习资料推荐

学习建议:

  • 相对来讲HTTP协议的常用知识不复杂,“基础篇”材料中,MDN 可以作为工具查询,“图解 HTTP” 与 “HTTP 权威指南” 选择一个阅读,作为体系化学习资料

  • 进阶篇中提供的是标准协议描述,感兴趣的同学阅读即可,也可作为工具使用

  • 基础篇

  • 进阶篇

    • Hypertext Transfer Protocol version 2 - RFC9113
    • HPACK - Header Compression for HTTP/2 - RFC7541

计网笔记

课堂笔记

初识HTTP

上面承载一些老三套和API,下面基于传输层协议

无状态,孤立的

TCP协议的特点是:

  • 面向连接

  • 点对点(一对一)

  • 可靠交付

  • 面向字节流,也就是说仅仅把上层协议传递过来的数据当成字节传输。为了实现TCP上述的特点,TCP协议需要解决的是面向连接(建立连接和关闭连接的方式)、可靠传输(错误确认和重传)、流量控制(发送方和接收方的传输速率协调)、拥塞控制四个方面。

协议发展

1.1是比较完整的,标准的

Request和Response首行不一样

Request 首行有方法 Resonse有状态码

状态码:

缓存

  • Cache-Control HTTP 头字段中的 no-cache 指示客户端不应直接从缓存中获取资源的副本,而应始终向服务器请求最新的资源。这意味着即使客户端已经缓存了资源,它也必须向服务器发起请求,并在服务器响应 200 OK 或 304 Not Modified 时才能使用缓存的副本。这可以确保客户端获取的始终是最新的资源,并避免使用过时或无效的资源。

以下是一个示例 HTTP 响应头,其中包含了 Cache-Control: no-cache

HTTP/1.1 200 OK
Content-Type: text/html; charset=UTF-8
Cache-Control: no-cache
Expires: Wed, 16 Feb 2023 10:00:00 GMT

在这个示例中,服务器告诉客户端不要使用缓存的资源,而应始终向服务器请求最新的资源。此外,Expires 头字段指示缓存过期时间,在本例中为 2023 年 2 月 16 日上午 10 点。这意味着在此时间之前,即使客户端已经缓存了该资源,它也必须向服务器发起请求以获取最新的资源。

需要注意的是,虽然 no-cache 表示客户端不应直接从缓存中获取资源的副本,但它并不禁止缓存,因此服务器仍然可以将资源缓存起来,只是在客户端请求时必须验证其有效性并确保其是最新的。

  • must-revalidate:即使有缓存,资源过期,必须验证之后才可以用

  • 协商缓存:能不能用最后要和server端通信

    • 请求和响应的响应头

全流程

304:请求的资源在上次请求后没有发生变化,客户端可以使用缓存的版本,而无需从服务器重新下载资源。当客户端请求一个资源时,如果该资源已经被客户端缓存了,并且缓存的版本是最新的,那么服务器会返回 304 Not Modified 状态码,告诉客户端可以使用缓存的版本。

cookie携带用户信息

set-cookie:response的响应头,用于向客户端发送一个 Cookie。

提出frame的概念

压缩算法,让传输更快

永久链接

流控制:控制计算资源

服务器推送:服务器智能的推送

允许服务器在客户端请求之前将一些资源推送到客户端,从而提高网页性能和加载速度。服务器推送功能是 HTTP/2 的一个重要特性,可以减少网络延迟和提高网站性能。

服务器推送的基本原理是,在客户端请求某个资源时,服务器可以同时推送该资源所依赖的其他资源,例如 JavaScript、CSS、图像等,以便客户端在请求这些资源时可以直接从本地缓存中获取,而无需再向服务器发送请求。这样可以减少网络延迟和带宽使用,提高网站性能和加载速度。

以下是一个服务器推送的示例:

  1. 客户端向服务器请求 index.html 页面。
  2. 服务器在响应中包含了 index.html 页面所依赖的其他资源,例如 style.cssscript.js
  3. 客户端收到响应后,会同时获取 index.htmlstyle.cssscript.js 三个资源,并将它们缓存到本地。
  4. 当客户端在后续的请求中需要获取 style.cssscript.js 时,它可以直接从本地缓存中获取,而无需再向服务器发送请求。

HTTP/2 的服务器推送功能可以通过以下几个步骤来实现:

  1. 客户端向服务器请求某个资源,例如 HTML 页面。
  2. 服务器向客户端发送请求的资源,并将该资源所依赖的其他资源推送到客户端。推送的资源可以通过 HTTP/2 的推送 Promise 机制来完成。
  3. 客户端收到推送的资源后,会将其缓存到本地。
  4. 当客户端需要获取推送的资源时,可以直接从本地缓存中获取,而无需再向服务器发送请求。

需要注意的是,服务器推送功能虽然可以提高网站性能和加载速度,但如果使用不当,也会导致资源浪费和安全问题。因此,在使用服务器推送功能时,需要考虑以下几个方面:

  1. 仅推送必要的资源:服务器推送的资源应该是客户端需要的、且不能从缓存中获取的资源。如果推送了大量不必要的资源,会导致带宽浪费和性能下降。
  2. 控制推送的资源数量:服务器推送的资源数量应该控制在合理的范围内。如果推送的资源过多,会导致客户端无法处理和缓存。
  3. 考虑安全性:由于服务器可以在未经请求的情况下将资源推送到客户端,因此需要考虑安全性问题。例如,不应该将敏感数据和信息推送到客户端。

场景分析

状态码200一定发起了请求码?

为什么说关闭标签页后第一次请求大部分是disk cache,当前刷新大部分是memory cache?

浏览器通常会将从服务器下载的资源缓存到本地磁盘或内存中,以便在后续的请求中可以更快地访问这些资源。磁盘缓存(Disk Cache)和内存缓存(Memory Cache)是浏览器缓存的两种形式,它们的缓存策略和缓存方式不同。

当关闭一个标签页后,浏览器会将该标签页中的所有资源从内存中移除,并将这些资源的缓存数据写入到磁盘缓存中。这是因为内存缓存的容量有限,关闭标签页后可以释放一些内存,以便浏览器更好地运行。当下次请求该网页时,浏览器会首先检查磁盘缓存中是否存在相应的资源,并从磁盘缓存中读取资源数据。这样可以快速地加载页面,并减少对服务器的请求。

当当前页面刷新时,浏览器会首先检查内存缓存中是否存在相应的资源,并从内存缓存中读取资源数据。这是因为内存缓存的访问速度比磁盘缓存更快,可以提高页面加载速度。如果内存缓存中不存在相应的资源,浏览器会从服务器请求资源,并将资源数据写入内存缓存中,以便后续访问时可以更快地加载页面。

需要注意的是,内存缓存的容量比磁盘缓存小,一些较大的资源可能无法完全存储在内存缓存中。此外,内存缓存的生命周期比磁盘缓存短,当关闭标签页时,内存缓存中的所有资源会被清空。因此,对于较大的资源或经常访问的资源,最好将其存储在磁盘缓存中,以便在后续访问时可以更快地加载页面。

除了缓存,第一次访问的时候可以使用CDN

那么如何保证他的缓存的最新的?

我们加入文件名或者版本号hash,每次刷新会不一样,就match不上了,就会访问新的缓存

SSO(Single Sign-On,单点登录)是一种身份验证和授权机制,它允许用户只需登录一次,即可在多个应用程序或系统中访问受保护的资源。SSO 可以减少用户登录的次数和减轻用户的记忆负担,同时提高了应用程序和系统的安全性和管理效率。

在 SSO 中,用户只需登录一次,就可以在多个应用程序或系统中访问受保护的资源。当用户在一个应用程序中访问受保护的资源时,该应用程序会向 SSO 服务器发送身份验证请求,SSO 服务器会验证用户的身份,并返回一个令牌(Token)给应用程序。应用程序可以使用该令牌来验证用户的身份,并授权其访问受保护的资源。当用户在另一个应用程序中访问受保护的资源时,该应用程序可以使用相同的令牌来验证用户的身份,并授权其访问受保护的资源,而无需再次登录。

SSO 通常使用以下两种方式来实现:

  1. 基于标准协议的 SSO:基于标准协议的 SSO 使用一些标准的身份验证和授权协议,如 SAML(Security Assertion Markup Language)或 OAuth 2.0。这种方式可以在不同的平台和系统之间实现 SSO,但需要在系统之间共享密钥和证书等安全信息。
  2. 基于企业身份验证和授权的 SSO:基于企业身份验证和授权的 SSO 使用企业内部的身份验证和授权机制,如 Active Directory 或 LDAP(Lightweight Directory Access Protocol)。这种方式通常用于企业内部的系统和应用程序之间,可以通过企业内部的身份验证和授权机制来实现 SSO。

SSO 的优点包括:

  1. 用户只需登录一次,可以在多个应用程序或系统中访问受保护的资源。
  2. 减少用户登录的次数和减轻用户的记忆负担。
  3. 提高应用程序和系统的安全性和管理效率。

需要注意的是,SSO 也存在一些安全风险,例如令牌泄露、中间人攻击等。因此,在实现 SSO 时,需要采取一些安全措施,如加密和签名令牌、使用 HTTPS 等。

strict-origin-when-cross-origin:隐私,referer只发送origin,防止URL上的隐私信息泄露 developers.google.com/web/updates…

因为他要去sso验证,是一个跨域请求

最后一个,因为默认https是443;http是80

跨域资源共享

大部分请求(复杂请求)会先发起一个预请求

跨域资源共享(Cross-Origin Resource Sharing,CORS)是一种浏览器的安全策略,用于在不同的域之间共享资源。CORS 通过 HTTP 头来告诉浏览器是否允许跨域访问资源,从而保护客户端和服务器之间的数据安全性。

CORS 主要涉及以下两个方面:

  1. 客户端:当客户端向服务器请求跨域资源时,会自动添加一个 Origin 头,该头包含了请求的源地址(协议、域名和端口号)。
  2. 服务器:服务器会检查请求的 Origin 头,并决定是否允许跨域访问资源。如果服务器允许跨域访问,则在响应头中添加 Access-Control-Allow-Origin 头,该头包含了允许访问资源的源地址。如果服务器不允许跨域访问,则返回错误码。

需要注意的是,CORS 仅适用于客户端和服务器之间的跨域请求,对于同源的请求无需进行跨域处理。同时,CORS 的安全性依赖于浏览器的实现,如果浏览器实现存在漏洞,可能会导致跨站脚本攻击(Cross-Site Scripting,XSS)等安全问题。

为了防止 CORS 跨域攻击,需要采取以下措施:

  1. 使用 HTTPOnly 和 Secure 标志:将 Cookie 设置为 HTTPOnly 和 Secure 标志,可以防止跨站脚本攻击。
  2. 使用双重认证:使用双重认证(如用户名密码和短信验证码)可以增加用户的安全认证。
  3. 限制数据范围:对于敏感数据,可以限制其访问范围,如只允许内部人员访问。
  4. 使用防火墙:使用防火墙和其他安全措施可以减少安全漏洞和攻击。

总之,CORS 是浏览器的安全策略,用于保护客户端和服务器之间的数据安全性。开发人员需要了解 CORS 的原理和实现方式,以及相应的安全措施,从而保证 Web 应用程序的安全性。

同域的代理服务器

Request 的 content-type是form

response的set-cookie

是无状态的?为什么下一次进入页面能记住登录态?

  • session+cookie

当登录成功之后,会提交登录信息给server,会生成session保存起来,并且用set-cookie种到相应的域名下

之后我们访问,就会把cookie携带出来,比较

JSON Web Token(JWT)是一种开放标准,用于在各方之间传输安全可靠的信息。JWT 可以通过数字签名验证数据的完整性和身份。JWT 通常用于身份验证和授权机制,它允许客户端和服务器之间在不共享密钥或会话状态的情况下进行身份验证。

JWT 的结构由三部分组成:头部(Header)、载荷(Payload)和签名(Signature):

  1. 头部(Header):包含了使用的算法和类型等信息,通常是一个 JSON 对象。
  2. 载荷(Payload):包含了一些声明和用户信息等信息,通常也是一个 JSON 对象。
  3. 签名(Signature):由头部和载荷中的数据和一个密钥生成的数字签名,用于验证数据的完整性和身份。

JWT 的生成和验证过程如下:

  1. 服务器生成 JWT,将头部和载荷中的数据进行加密,然后添加签名生成 JWT。
  2. 服务器将生成的 JWT 发送给客户端。
  3. 客户端将 JWT 存储在本地,用于后续请求的身份验证和授权。
  4. 客户端在请求中将 JWT 发送给服务器。
  5. 服务器验证 JWT 的有效性和签名是否正确,如果验证通过,则允许客户端访问相应的资源。

JWT 的优点包括:

  1. 可以跨平台使用,不需要共享密钥或会话状态。
  2. 可以包含任意数据,如用户信息、权限等信息。
  3. 可以通过数字签名验证数据的完整性和身份,提高安全性。

需要注意的是,由于 JWT 是一种开放标准,任何人都可以使用 JWT 来生成和验证身份验证和授权信息。因此,在使用 JWT 时,需要注意一些安全问题,如密钥管理、签名算法、Token 时效性等问题。

适合使用jwt的场景:

  • 有效期短
  • 只希望被使用一次

比如,用户注册后发一封邮件让其激活账户,通常邮件中需要有一个链接,这个链接需要具备以下的特性:能够标识用户,该链接具有时效性(通常只允许几小时之内激活),不能被篡改以激活其他可能的账户,一次性的。这种场景就适合使用jwt。

而由于jwt具有一次性的特性。单点登录和会话管理非常不适合用jwt,如果在服务端部署额外的逻辑存储jwt的状态,那还不如使用session。基于session有很多成熟的框架可以开箱即用,但是用jwt还要自己实现逻辑。

怎么做到跳转的界面自动登录了?

实战

如何发起HTTP协议

XHR对象

钩子回调

XMLHttpRequest 是一种在浏览器中进行 HTTP 请求和响应的 API。它允许客户端通过 JavaScript 向服务器发送请求,并处理服务器返回的响应。XMLHttpRequest 可以实现异步请求和服务器推送等功能,是实现 Web 应用程序的重要组成部分。

XMLHttpRequest 的主要用途包括:

  1. 发送 HTTP 请求:通过 XMLHttpRequest 可以发送 HTTP GET、POST、PUT、DELETE 等请求,向服务器请求数据和资源。
  2. 处理服务器响应:当服务器返回响应时,XMLHttpRequest 可以处理服务器返回的数据和状态码,进行相应的处理和操作。
  3. 异步请求:XMLHttpRequest 支持异步请求,允许客户端在不阻塞用户界面的情况下进行请求和处理响应。

XMLHttpRequest 的基本使用步骤如下:

  1. 创建 XMLHttpRequest 对象:可以通过 new XMLHttpRequest() 来创建一个 XMLHttpRequest 对象。
  2. 打开请求:使用 open() 方法打开一个请求。open() 方法接受三个参数:HTTP 请求的方法、请求的 URL、是否异步请求。
  3. 发送请求:使用 send() 方法发送请求。send() 方法接受一个参数,通常是请求的数据。
  4. 处理响应:当服务器返回响应时,XMLHttpRequest 会触发一个 readyStateChange 事件。可以通过设置 onreadystatechange 属性来指定响应处理函数。
  5. 获取响应数据:可以通过 responseText 或者 responseXML 属性获取响应数据。

需要注意的是,由于 XMLHttpRequest 受到同源策略的限制,只能向与当前页面同源的服务器发送请求。如果要向其他域名的服务器发送请求,需要使用跨域资源共享(CORS)等技术。

Fetch 的优点包括:

  1. API 设计简单:Fetch 的 API 设计比 XHR 更加简单和易于使用,使用 Promise 来处理异步请求和响应。
  2. 支持 Request 和 Response 对象:Fetch 支持 Request 和 Response 对象,可以更加灵活地处理请求和响应,如添加和修改请求头、响应头等信息。
  3. 内置的 CORS 支持:Fetch 内置了 CORS 支持,可以更加方便地进行跨域请求。

Fetch 的缺点包括:

  1. 兼容性问题:Fetch 不支持低版本的浏览器,需要使用 polyfill 或者其他库来实现兼容性。
  2. 请求和响应的错误处理:Fetch 对请求和响应的错误处理不够灵活,如不能处理超时错误等。

XHR 的优点包括:

  1. 兼容性好:XHR 在大部分浏览器中都有良好的兼容性,可以支持低版本的浏览器。
  2. 可以处理复杂的请求和响应:XHR 支持更多的请求和响应处理方式,如同步请求、流式响应等,可以更加灵活地处理请求和响应。
  3. 处理请求和响应的错误:XHR 支持更加灵活的请求和响应错误处理,如可以处理超时错误等。

XHR 的缺点包括:

  1. API 设计复杂:XHR 的 API 设计较为复杂,使用事件监听器来处理异步请求和响应。

  2. 需要手动处理跨域请求:XHR 对跨域请求支持不够友好,需要手动处理跨域请求,如设置跨域请求头等。

axios库比较好用

Client 和 server可以使用websocket

利用无连接的UDP协议