• HTTP 面试知识点提炼


    前言

    由于很多小伙伴看了 《普通人如何进大厂》这篇文章对我的笔记比较感兴趣,所以我花时间整理提炼了一下跟大家分享,不保证内容完全正确,仅供参考哈

    其他笔记传送门

    从输入 URL 到页面加载完成,发生了什么?

    1、HTTP 请求准备阶段

    • 构建请求

    浏览器构建请求行信息,准备发起网络请求 GET /index.html HTTP1.1

    • 查找缓存

    如果浏览器发现请问资源在浏览器中存在副本,根据强缓存规则,如没有过期那么直接返回资源,如何查找

    失败进入下一个环节:

    • 准备 ip 地址和端口
    • DNS(域名和ip的映射系统) 域名解析,拿到ip之后找端口,默认为80
    • 建立tcp链接(三次握手)
    • 如果是https 还需要建立TLS连接

    2、HTTP 发送请求

    • 浏览器向服务端发起http请求,把请求头和请求行一起发送个服务器,服务端解析请求头如发现cache-control和etag(if-none-match),if-modified(if-modified-since)字段就会判断缓存是否过期,如果没有返回304,否则返回200

    3、HTTP 响应返回

    • 浏览器拿到响应数据,首先判断是否是4XX或者5XX是就报错,如果是3XX就重定向,2XX就开始解析文件,如果是gzip就解压文件

    • TCP断开连接

      4次挥手

    • 浏览器解析渲染

      建立根据html建立dom树和css树,如果遇到script首选判断是否defer和async否则会阻塞渲染并编译执行js,如果没有则组合生成render tree,最后浏览器开启GPU进行绘制合成图层,将内容显示屏幕。

    HTTP0.9 特性

    • 没有请问头和请求体只有请求行
    • 只能发送html文件

    HTTP1.0 特性

    • 可以发送javaScript、CSS、图片、音频
    • 加上请求头和请求体
    • 状态码
    • cache 机制
    • 每进行一次 HTTP 通信,都需要经历建立 TCP 连接、传输 HTTP 数据和断开 TCP 连接三个阶段

    HTTP1.1 特性

    • 持久连接的方法,它的特点是在一个 TCP 连接上可以传输多个 HTTP 请求,只要浏览器或者服务器没有明确断开连接,那么该 TCP 连接会一直保持(提高性能)

    • 持久连接虽然能减少 TCP 的建立和断开次数,但是它需要等待前面的请求返回之后,才能进行下一次请求。如果 TCP 通道中的某个请求因为某些原因没有及时返回,那么就会阻塞后面的所有请求,这就是著名的队头阻塞的问题(在 HTTP 1.1 中,每一个链接都默认是长链接,因此对于同一个 TCP 链接,HTTP 1.1 规定:服务端的响应返回顺序需要遵循其接收到相应的顺序。但这样存在一个问题:如果第一个请求处理需要较长时间,响应较慢,将会“拖累”其他后续请求的响应,这是一种队头阻塞。)

    • 引入了 Cookie、虚拟主机的支持、对动态内容的支持

    • 浏览器为每个域名最多同时维护 6 个 TCP 持久连接(提高性能)

    • 使用 CDN 的实现域名分片机制。(提高性能)

    • 对带宽的利用率却并不理想(tcp 启动慢、头部堵塞、tcp 竞争)

    HTTP2 特点

    • 只使用一个 TCP 长连接来传输数据,实现资源的并行请求,也就是任何时候都可以将请求发送给服务器,解决头部堵塞(多路复用)

    • 二进制传输

    • 多路复用(原理二进制分帧层,携带id的帧流到服务器)

    单一的长连接,减少了 SSL 握手的开销,多路复用能大幅提高传输效率,不用等待上一个请求的响应,加大cpu 的使用率

    • 头部压缩

    头部被压缩,减少了数据传输量

    • 服务端推送

    有了二进制分帧层还能够实现请求的优先级、服务器推送、头部压缩等特性,从而大大提升了文件传输效率

    但是HTTP2还是会存在 tcp 堵塞(理解,http 堵塞就是需要等待前面的http包发送完成而造成的等待,tcp 堵塞是TCP 传输过程中,由于单个数据包的丢失而造成的阻塞)

    HTTP3

    QUIC 看成是集成了“TCP+HTTP/2 的多路复用 +TLS 等功能

    TCP与UDP的区别

    1、基于连接与无连接;

    2、对系统资源的要求(TCP较多,UDP少);

    3、UDP程序结构较简单;

    4、流模式与数据报模式 ;

    5、TCP保证数据正确性,UDP可能丢包;

    6、TCP保证数据顺序,UDP不保证。

    TCP 握手过程

    • 建立tcp链接(三次握手,客户端发送 syn=j 给服务端然后处于 syn_send 状态;

    • 服务端接受到syn,然后发送自己的syn包syn=k,和 ack=j+1(确认客户端包),状态为 syn_recv;

    • 客户端收到ack和syn则发送 ack=k+1给服务端表示确认,服务端和客户端都进入了establish状态),

    • 为什么要3次握手:确认客户端的接收、发送能力正常,服务器自己的发送、接收能力也正常

    HTTP 缓存

    强缓存(浏览器内部完成)

    max-age:数值,单位是秒,从请求时间开始到过期时间之间的秒数。基于请求时间(Date字段)的相对时间间隔,而不是绝对过期时间

    expires:和max-age一样指缓存过期时间,但是他的指定了具体时间GMT格式,HTTP/1.1,Expire已经被Cache-Control替代,原因在于Expires控制缓存的原理是使用客户端的时间与服务端返回的时间做对比,那么如果客户端与服务端的时间因为某些原因(例如时区不同;客户端和服务端有一方的时间不准确)发生误差,那么强制缓存则会直接失效,这样的话强制缓存的存在则毫无意义

    协商缓存(需要询问服务器)

    Last-Modified/If-Modified-Since(服务端时间对比):本地文件在服务器上的最后一次修改时间。缓存过期时把浏览器端缓存页面的最后修改时间发送到服务器去,服务器会把这个时间与服务器上实际文件的最后修改时间进行对比,如果时间一致,那么返回304,客户端就直接使用本地缓存文件。(浏览器最后修改时候和服务端对比,如果一致则走缓存)

    问题:

    • 现在大多数服务端都采用了负载均衡策略,可能导致不同虚拟主机返回的Last-Modified时间戳不一致,导致对比失败~
    • 文件也许会周期性的更改,但是他的内容并不改变,不希望客户端重新get

    Etag/If-None-Match:(EntityTags,内容摘要)是URL的tag,用来标示URL对象是否改变,一般为资源实体的哈希值。和Last-Modified类似,如果服务器验证资源的ETag没有改变(该资源没有更新),将返回一个304状态告诉客户端使用本地缓存文件。Etag的优先级高于Last-Modified,Etag主要为了解决 Last-Modified无法解决的一些问题。

    文件缓存策略

    1. 有文件指纹:index.html 用不用缓存,其他用强缓存+文件指纹
    2. 无指纹:index.html 用不用缓存,其他用协商etag缓存(文件变了就缓存)

    HTTPS

    原理

    服务器端的公钥和私钥,用来进行非对称加密

    客户端生成的随机密钥,用来进行对称加密

    • A 与 B 通信(被监听)

    • A 给 B 一个对成密钥(对称加密)(密钥可能被劫持)

    • A 有自己的公钥和私钥(并且只要自己的私钥解开公钥)B也是有自己的公私钥,但每次通信都要解密特别麻烦(非对称加密)

    • A 直接把公钥发给B,然后让B通过公钥加密‘对称密钥’,效率就快很多

    • 那么这里又存在一个问题 A 传给 B 的公钥被截取了然后冒充 A跟B通信

    • 所以就有了ca验证中心证明 A就是A

    完整流程:

    那么A直接把公钥发和证书给 B,B 通过 ca 验证A身份后后,通过A的公钥加密‘对称密钥’发给A,A用自己的私钥解密得到了‘对称密钥’,以后就通过对称加密方式交流

    通讯流程

    • 浏览器发起请求

    • 服务器返回公钥+签名证书

    • 浏览器向CA认证中心询问证书是否有效

    • CA认证返回结果

    • 浏览器用公钥加密对称秘钥

    • 服务器用自己的私钥解密 对称称秘钥,发起通讯

    http 请求方法

    post 和 put 的区别

    • 都能新增和修改数据

    • put 无副作用,调用一次和多次效果相同,post 调用每次都会新增

    • post 面向资源集合,put 面向单资源

    put 和 patch 的区别

    他两都是同来更新数据的,而patch是同来更新局部资源比如某个对象只更改了某个字段则可以用 patch

    常见状态吗

    • 206 部分内容,代表服务器已经成功处理了部分GET请求,可以应用断点陆续上传
    • 301 永久重定向
    • 302 临时重定向
    • 304 命中协商缓存
    • 400 请求报文存在语法错误
    • 401 需求http认证
    • 403 请求资源被服务器拒绝
    • 404 服务端找不到资源
    • 500 服务端执行请求发送错误
    • 501 请求超出服务端能力范围(不支持某个方法)
    • 502 作为网关或者代理工作的服务器尝试执行请求时,从远程服务器接收到了一个无效的响应
    • 503 由于超载或系统维护,服务器暂时的无法处理客户端的请求

    HTTP 缓存

    http 缓存过程

    1. 客户端向服务端发起第一次请求资源
    • 服务端返回资源,并通过响应头返回缓存策略
    • 客服端根据缓存策略将策略和资源缓存起来

    结论:

    • 浏览器每次发起请求,都会先在浏览器缓存中查找该请求的结果以及缓存标识
    • 浏览器每次拿到返回的请求结果都会将该结果和缓存标识存入浏览器缓存中

    1. 当客户端再次向服务端发起请求时
    • 客户端判断是否有缓存,有则判断是否存在 cache-control,并根据max-age 判断其是否已过期,没有过期直接读取缓存,返回200

    • 若已过期则携带缓存策略if-none-match发送到服务端

    • 服务端根据 etag 与if-none-match 相同则返回304继续使用缓存,更新新鲜度

    • 不相同则重新返回资源

    缓存位置

    • from memory cache代表使用内存中的缓存,

    • from disk cache则代表使用的是硬盘中的缓存,浏览器读取缓存的顺序为memory –> disk

    • 内存缓存(from memory cache):内存缓存具有两个特点,分别是快速读取和时效性:

    • 快速读取:内存缓存会将编译解析后的文件,直接存入该进程的内存中,占据该进程一定的内存资源,以方便下次运行使用时的快速读取。

    • 时效性:一旦该进程关闭,则该进程的内存则会清空。

    • 硬盘缓存(from disk cache):硬盘缓存则是直接将缓存写入硬盘文件中,读取缓存需要对该缓存存放的硬盘文件进行I/O操作,然后重新解析该缓存内容,读取复杂,速度比内存缓存慢。

    在浏览器中,浏览器会在js和图片等文件解析执行后直接存入内存缓存中,那么当刷新页面时只需直接从内存缓存中读取(from memory cache);而css文件则会存入硬盘文件中,所以每次渲染页面都需要从硬盘读取缓存(from disk cache)

    Web安全防御

    xss 跨域脚本攻击(利用网站对用户的信任)

    1. 非持久型 - url参数直接注入 脚本,伪造成正常域名诱惑用户点击访问(浏览器默认防范?)
    2. 持久型 - 存储到DB后读取时注入 (灾难) 两者都是通过脚本获取cookies 然后通过img或者ajax请求发送到黑客服务器 防范手段:
    • html字符转译,或者只过滤script这些脚步

    • 限制资源请求来源csp

    • cookies 防范: value 如果用于保存用户登录态,应该将该值加密,不能使用明文的用户标识 http-only 不能通过 JS 访问 Cookie,减少 XSS 攻击
      Content-Security-Policy: img-src https://* 只允许加载 HTTPS 协议图片 Content-Security-Policy: default-src ‘self’ 只允许加载本站资源

    • 前端方案:设置 meta 标签的方式

    Csrf 跨域请求伪造(利用用户对网站的信任):

    即跨站请求伪造,是一种常见的Web攻击,它利用用户已登录的身份,在用户毫不知情的情况下,以用户的名义完成非法操作 在A网站没有退出的情况下,引诱用户访问第三方网站(评论发链接)

    访问页面自动发起请求 第三方默认给A发起请求

    防御:

    • Get 请求不对数据进行修改

    • 不让第三方网站访问到用户 Cookie

    • 阻止第三方网站请求接口

    • 请求时附带验证信息,比如验证码或者 Token

    http 和 websocket 的区别

    相同点主要

    1. 都是基于TCP的应用层协议;

    2. 都使用Request/Response模型进行连接的建立;

    3. 在连接的建立过程中对错误的处理方式相同,在这个阶段WS可能返回和HTTP相同的返回码;

    4. 都可以在网络中传输数据。

    不同之处

    1. WS使用HTTP来建立连接,但是定义了一系列新的header域,这些域在HTTP中并不会使用;

    2. WS的连接不能通过中间人来转发,它必须是一个直接连接;

    3. WS连接建立之后,通信双方都可以在任何时刻向另一方发送数据;

    4. WS连接建立之后,数据的传输使用帧来传递,不再需要Request消息;

    5. WS的数据帧有序。

    作者:Ali酱
    链接:https://juejin.cn/post/7035067081200500750
    来源:稀土掘金
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

  • 相关阅读:
    oracle用一条sql查出哪些数据不在某个表里
    RISCV学习笔记7.10(开源虚拟机篇)--AlmaLinux虚拟机安装python与labview自动化软件
    Qt绘图机制
    PC端 VUE 官网项目 前端开发 响应式布局(宽+高 等比例缩放)
    Graphpad Prism10.2.1(395) 安装教程 (含Win/Mac版)
    VINS-Mono-后端优化 (一:预积分残差计算-IMU预积分约束)
    WPF绑定单变量Binding和绑定多变量MultiBinding 字符串格式化 UI绑定数据,数据变化自动更新UI,UI变化自动更新数据
    Visual Prompt Tuning 笔记
    RegAD-Registration based Few-Shot Anomaly Detection论文学习
    2022学年第一学期郑州大学ACM招新赛&选拔赛
  • 原文地址:https://blog.csdn.net/qq_57676486/article/details/133082222