HTTP协议

232 阅读37分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

1、 常见的HTTP请求方式?

  • GET:获取数据
  • POST:创建数据
  • PUT:修改数据
  • DELETE:删除数据
  • OPTIONS:询问支持的请求方法,用来跨域请求
  • HEAD:获取报文头部,与get相比,不返回报文主体部分
  • CONNECT:要求在与代理服务器通信时建立隧道,使用隧道进行TCP通信;
  • TRACE: 回显服务器收到的请求,主要⽤于测试或诊断。

2、 传统url请求与RESTful区别?

传统url请求:

  • 查询GET: /user/query?name=tom
  • 详情GET: /user/getInfo?id=1
  • 创建POST: /user/create?name=tom
  • 修改POST: /user/update?id=1&name=tom
  • 删除GET: /user/delete?id=1

RESTful风格:

  • 查询GET: /user?name=tom
  • 详情GET: /user/1
  • 创建POST: /user
  • 修改PUT: /user/1
  • 删除DELETE: /user/1

RESTful特点:

  • 使用URL描述资源
  • 使用HTTP方法描述行为。使用HTTP状态码来表示不同的结果
  • 使用json交互数据,传统模式使用的是键值对形式
  • RESTful 只是一种风格,并不是强制的标准。

3、GET 和 POST请求的区别?

  • 参数方式: get参数拼接在url上,使用params;post参数放在请求体内,使用data
  • 请求长度: 由于浏览器对url的长度限制,所以影响get发送请求时的长度,这个长度是浏览器规定的;post传输数据没有限制
  • 应用场景: get 请求是一个幂等的请求,一般 get 请求用于对服务器资源不会产生影响的场景,比如说请求一个网页的资源。而 post 不是一个幂等的请求,一般用于对服务器资源会产生影响的情景,比如注册用户这一类的操作。
  • 是否缓存: 浏览器一般对get 进行缓存,不对post缓存
  • 安全性: get的参数是放于url中向服务器发送请求,不安全,因为保留在历史记录中;post的url不可见,安全,post可用于防止CSRF

4、GET方法url长度限制的原因?

实际上HTTP协议未对url长度进行限制,而是特定的浏览器或服务器对url长度的限制。IE浏览器是长度限制数是2083字节(2K+35),是浏览器中对url长度限制数最小的,所以只要不超过2083字节,在所有浏览器中工作都不会有问题。

主流的浏览器限制数:

  • Microsoft Internet Explorer (Browser):IE浏览器对URL的最大限制为2083个字符,如果超过这个数字,提交按钮没有任何反应。
  • Google (chrome):URL最大长度限制为 8182 个字符。
  • Firefox (Browser):URL最大长度限制为 65,536 个字符。
  • Safari (Browser):URL最大长度限制为 80,000 个字符。
  • Opera (Browser):URL最大长度限制为 190,000 个字符。

主流服务器限制数:

  • Apache (Server):能接受最大url长度为8192个字符。
  • Microsoft Internet Information Server(IIS):能接受最大url的长度为16384个字符。

所以只要不超过2083个字符,所有的浏览器或服务器都可正常工作。

5、POST 和 PUT请求的区别?

  • POST是创建数据,post向服务器发送请求,会改变数据的种类资源,会创建新的内容
  • PUT是修改数据,put向服务器发送请求,修改数据,不会重新添加数据

6、OPTIONS请求方法及使用场景?

HTTP 的 OPTIONS 方法 用于获取目的资源所支持的通信选项。客户端可以对特定的 URL 使用 OPTIONS 方法,也可以对整站(通过将 URL 设置为“*”)使用该方法。

实际上,出于安全考虑,并不是所有域名访问后端服务都可以。其实在正式跨域之前,浏览器会根据需要发起一次预检(也就是option请求),用来让服务端返回允许的方法(如get、post),被跨域访问的Origin(来源或者域)等。

CORS中的预检请求:

  • 浏览器请求,预检请求报文中的 Access-Control-Request-Method 首部字段告知服务器实际请求所使用的 HTTP 方法
  • Access-Control-Request-Headers 首部字段告知服务器实际请求所携带的自定义首部字段。服务器基于从预检请求获得的信息来判断,是否接受接下来的实际请求。
Access-Control-Request-Method: POST
Access-Control-Request-Headers: X-PINGOTHER, Content-Type
  • 服务器所返回的 Access-Control-Allow-Methods 首部字段将所有允许的请求方法告知客户端。该首部字段与 Allow 类似,但只能用于涉及到 CORS 的场景中。
Access-Control-Allow-Origin: http://foo.example
Access-Control-Allow-Methods: POST, GET, OPTIONS
Access-Control-Allow-Headers: X-PINGOTHER, Content-Type

7、常见的HTTP请求头和响应头?

1. HTTP Request Headers常见的请求头:

  • accept: 浏览器接受类型,例如application/json
  • accept-Encoding: 浏览器能处理的压缩类型,例如gzip
  • accept-Language: 浏览器当前设置的语言
  • connection: 浏览器与服务器之间连接的类型,例如keep-alive,一次TCP请求可多次使用
  • cookie: 当前页面设置的cookie值
  • host: 发送请求页面的域名,例如 www.baidu.com
  • referer: 发送请求页面的url,例如www.baidu.com
  • user-agent: 浏览器信息,例如Chrmoe/102.0.5005.63

2. HTTP Reponse Headers常见的响应头:

  • content-type: 服务器返回的类型,例如application/json;charset=utf-8
  • content-length: 返回的长度
  • content-encoding: 返回的压缩类型,例如gzip
  • set-cookie:服务器端改cookie值

3. 与缓存相关的头:

强制缓存

  • cache-control: 是否作缓存,no-cache不作缓存,max-age作缓存,缓存过期时间,max-age=31536000代表资源有效期是31536000秒
  • expires: 代表资源失效时间,在这个时间之前都有效,以前用来使用的http头,现在用cache-control代替 协商缓存
  • etag: 资源唯一标识字符串(类似指纹)
  • if-none-match: 再次访问服务器时Request Headers中带的,例如if-none-match:etag内容
  • last-modified: 资源最后修改时间
  • if-modified-since: 再次访问服务器时Request Headers中带的,例如if-modified-since:last-modified内容

image.png

image.png

image.png

8、HTTP缓存机制?

  1. 为什么进行缓存? 浏览器在用户的本地磁盘存储了用户最近请求的静态资源,css,js,图片等资源。当用户再次请求同一资源时,浏览器直接从本地磁盘读取资源即可。
  • 加快客户端加载网页的速度,提升用户体验
  • 减少多余的数据传输
  • 减轻服务器端的负担
  1. 缓存方法及过程:
  • 强制缓存:
    • 浏览器第一次访问服务器,没有缓存,服务器返回数据,状态码200,浏览器从服务器上下载资源文件,并缓存资源文件和response header及header中cache-control
    • 浏览器再次请求某一资源时,会先获取该资源的header信息。
    • 根据header信息中的expires和cache-control ,将时间与上次返回200的时间作比较,查看是否超过cache-controlmax-age,去判断该资源是否过期。若未过期,是强缓存,则直接在缓存中获取资源,不向服务器发送请求。如果浏览器不支持 HTTP1.1,则使用 expires 头判断是否过期;
  • 协商缓存:
    • 浏览器第一次访问服务器,没有缓存,服务器返回数据,状态码200,浏览器从服务器上下载资源文件,并缓存资源文件和response header及header中cache-control
    • 浏览器再次请求某一资源时,会先获取该资源的header信息。
    • 根据header信息中的expires和cache-control ,将时间与上次返回200的时间作比较,查看是否超过cache-controlmax-age,去判断该资源是否过期。若未过期,是强缓存,则直接在缓存中获取资源,不向服务器发送请求。如果浏览器不支持 HTTP1.1,则使用 expires 头判断是否过期;
    • 如果过期了,浏览器只能再给服务器发送请求。客户端会将第一次请求时,服务器所给的etag和last-modified,分别赋给if-none-match和if-modified-since。服务器对比客户端etag/if-none-match和last-modified和if-modified-since。服务器会优先验证etag,一致则命中协商缓存
    • 如果与服务器上的标识一样,说明内容是最新的,返回304,客户端继续使用本地缓存;如果不同的,资源修改,返回200。
    • 如果服务器收到的请求没有 etag 值,则将 if-modified-since 和被请求文件的最后修改时间做比对,一致则命中协商缓存,返回 304;不一致则返回新的 last-modified 和文件并返回 200

第一次请求: image.png 再次请求:

image.png

很多网站的资源后面都加了版本号,这样做的目的是:每次升级了 JS 或 CSS 文件后,为了防止浏览器进行缓存,强制改变版本号,客户端浏览器就会重新下载新的 JS 或 CSS 文件 ,以保证用户能够及时获得网站的最新更新

9、HTTP请求报文是什么样的?

请求报文由4部分组成:

  • 请求行: 请求⽅法字段、URL字段、HTTP协议版本字段
  • 请求头: 请求头部由关键字/值对组成,每⾏⼀对,关键字和值⽤英⽂冒号“:”分隔
  • 空行
  • 请求体: post put等请求携带的数据

GET请求:

image.png

POST请求:

image.png

image.png

10、HTTP响应报文是什么样的?

响应报文由4部分组成:

  • 响应行: 由网络协议版本,状态码和状态码的原因短语组成
  • 响应头: 响应名与对应的响应值
  • 空行
  • 响应体: 服务器响应的数据

image.png

11、对keep-alive的理解?

HTTP1.0 中默认是在每次请求/应答,客户端和服务器都要新建一个连接,完成之后立即断开连接,这就是短连接

当使用Keep-Alive模式时,Keep-Alive功能使客户端到服务器端的连接持续有效,当出现对服务器的后续请求时,Keep-Alive功能避免了建立或者重新建立连接,这就是长连接

其使用方法如下:

  • HTTP1.0版本是默认没有Keep-alive的,所以要想连接得到保持,必须手动配置发送Connection: keep-alive字段。若想断开keep-alive连接,需发送Connection:close字段;
  • HTTP1.1规定了默认保持长连接,数据传输完成了保持TCP连接不断开,等待在同域名下继续用这个通道传输数据。如果需要关闭,需要客户端发送Connection:close首部字段。

keep-alive的建立过程:

  • 客户端向服务器端发送请求报文的同时加上connection: keep-alive
  • 服务器端收到并处理connection
  • 服务器端向客户端发送数据,并返回connection:keep-alive
  • 客户端收到connection,建立连接

服务端自动断开过程(也就是没有keep-alive):

  • 客户端向服务器只是发送内容报文(不包含Connection字段)
  • 服务器收到请求并处理
  • 服务器返回请求的资源并关闭连接
  • 客户端接收资源,发现没有Connection字段,断开连接

客户端请求断开连接过程:

  • 客户端向服务器发送Connection:close字段
  • 服务器收到请求并处理connection字段
  • 服务器返回响应资源并断开连接
  • 客户端接收资源并断开连接

开启Keep-Alive的优点:

  • 较少的CPU和内存的使⽤(由于同时打开的连接的减少了);
  • 允许请求和应答的HTTP管线化;
  • 降低拥塞控制 (TCP连接减少了);
  • 减少了后续请求的延迟(⽆需再进⾏握⼿);
  • 报告错误⽆需关闭TCP连;

开启Keep-Alive的缺点:

  • 长时间的Tcp连接容易导致系统资源无效占用,浪费系统资源。

12、常见的HTTP状态码有哪些?

1. 1xx: 请求到服务器,接受的请求正在处理

2. 2xx: 成功

1. 200 成功
2. 204 No Content:

表示客户端发送的请求已经在服务器端正常处理了,但是没有返回的内容,响应报文中不包含实体的主体部分。一般用于客户端向服务器端发送信息,服务器端不需要返回时使用。

image.png

3. 206 Partial Content:

表示客户端 进行了范围请求,而服务器端执行了这部分的GET请求,响应报文中包含由Content-Range指定范围的实体内容。

3. 3xx: 重定向

1. 301 永久重定向

表示请求的资源已经被分配了新的 URI,以后应使用资源指定的 URI。新的 URI 会在 HTTP 响应头中的 Location 首部字段指定。若用户已经把原来的URI保存为书签,此时会按照 Location 中新的URI重新保存该书签。同时,搜索引擎在抓取新内容的同时也将旧的网址替换为重定向之后的网址。 使用场景:

  • 当我们想换个域名,旧的域名不再使用时,用户访问旧域名时用301就重定向到新的域名。其实也是告诉搜索引擎收录的域名需要对新的域名进行收录。
  • 在搜索引擎的搜索结果中出现了不带www的域名,而带www的域名却没有收录,这个时候可以用301重定向来告诉搜索引擎我们目标的域名是哪一个。
2. 302 临时重定向

表示请求的资源被分配到了新的 URI,希望用户本次能使用新的 URI 访问资源。和 301状态码相似,但是 302 代表的资源只是临时性质的。也就是说已移动的资源对应的 URI 将来还有可能发生改变。若用户把 URI 保存成书签,但不会像 301 状态码出现时那样去更新书签,而是仍旧保留返回 302 状态码的页面对应的 URI。同时,搜索引擎会抓取新的内容而保留旧的网址。因为服务器返回302代码,搜索引擎认为新的网址只是暂时的。

使用场景:

  • 当我们在做活动时,登录到首页自动重定向,进入活动页面。
  • 未登陆的用户访问用户中心重定向到登录页面。
  • 访问404页面重新定向到首页。

例如在百度搜索js,点菜鸟教程是,点进去是www.baidu,com...., 返回302,location跳转到新连接

image.png

3. 303 资源存在另一个url,应使用GET方法获取资源

表示由于请求对应的资源存在着另一个 URI,应使用 GET 方法定向获取请求的资源。 303 状态码和 302 Found 状态码有着相同的功能,但是 303 状态码明确表示客户端应当采用 GET 方法获取资源。

303 状态码通常作为 PUT 或 POST 操作的返回结果,它表示重定向链接指向的不是新上传的资源,而是另外一个页面,比如消息确认页面或上传进度页面。而请求重定向页面的方法要总是使用 GET。

注意:

  • 当 301、302、303 响应状态码返回时,几乎所有的浏览器都会把 POST 改成GET,并删除请求报文内的主体,之后请求会再次自动发送。
  • 301、302 标准是禁止将 POST 方法变成 GET方法的,但实际大家都会这么做。
4. 304 资源未被修改,协商缓存

浏览器再次请求某一资源时,会先获取该资源的header信息。根据header信息中的expires和cache-control 去判断该资源是否过期。若未过期,是强缓存,则直接在缓存中获取资源,不向服务器发送请求。

如果过期了,浏览器只能再给服务器发送请求。客户端会将第一次请求时,服务器所给的etag和last-modified,分别赋给if-none-match和if-modified-since。服务器对比客户端etag/if-none-match和last-modified和if-modified-since,如果与服务器上的标识一样,说明内容是最新的,返回304,客户端继续使用本地缓存;如果不同的,资源修改,返回200。

状态码304并不是一种错误,而是告诉客户端有缓存,直接使用缓存中的数据。返回页面的只有头部信息,是没有内容部分的,这样在一定程度上提高了网页的性能。

5. 307 临时重定向

该状态码与 302 Found 有着相同含义,尽管 302 标准禁止 POST 变成 GET,但是实际使用时还是这样做了。

307 会遵守浏览器标准,不会从 POST 变成 GET。但是对于处理请求的行为时,不同浏览器还是会出现不同的情况。

4. 4xx: 客户端错误

1. 400 Bad Request 请求报文中有语法错误

错误发生时,需修改请求的内容后再次发送请求。另外,浏览器会像 200 OK 一样对待该状态码。

2. 401 Unauthorized 未通过HTTP认证

表示发送的请求需要有通过 HTTP 认证(BASIC 认证、DIGEST 认证)的认证信息。若之前已进行过一次请求,则表示用户认证失败

返回含有 401 的响应必须包含一个适用于被请求资源的 WWW-Authenticate 首部用以质询(challenge)用户信息。当浏览器初次接收到 401 响应,会弹出认证用的对话窗口。

以下情况会出现401:

  • 401.1 - 登录失败。
  • 401.2 - 服务器配置导致登录失败。
  • 401.3 - 由于 ACL 对资源的限制而未获得授权。
  • 401.4 - 筛选器授权失败。
  • 401.5 - ISAPI/CGI 应用程序授权失败。
  • 401.7 - 访问被 Web 服务器上的 URL 授权策略拒绝。这个错误代码为 IIS 6.0 所专用。
3. 403 Forbidden 没有权限

表示请求资源的访问被服务器拒绝了,服务器端没有必要给出详细理由,但是可以在响应报文实体的主体中进行说明。进入该状态后,不能再继续进行验证。该访问是永久禁止的,并且与应用逻辑密切相关。

IIS 定义了许多不同的 403 错误,它们指明更为具体的错误原因:

  • 403.1 - 执行访问被禁止。
  • 403.2 - 读访问被禁止。
  • 403.3 - 写访问被禁止。
  • 403.4 - 要求 SSL。
  • 403.5 - 要求 SSL 128。
  • 403.6 - IP 地址被拒绝。
  • 403.7 - 要求客户端证书。
  • 403.8 - 站点访问被拒绝。
  • 403.9 - 用户数过多。
  • 403.10 - 配置无效。
  • 403.11 - 密码更改。
  • 403.12 - 拒绝访问映射表。
  • 403.13 - 客户端证书被吊销。
  • 403.14 - 拒绝目录列表。
  • 403.15 - 超出客户端访问许可。
  • 403.16 - 客户端证书不受信任或无效。
  • 403.17 - 客户端证书已过期或尚未生效
  • 403.18 - 在当前的应用程序池中不能执行所请求的 URL。这个错误代码为 IIS 6.0 所专用。
  • 403.19 - 不能为这个应用程序池中的客户端执行 CGI。这个错误代码为 IIS 6.0 所专用。
  • 403.20 - Passport 登录失败。这个错误代码为 IIS 6.0 所专用。
4. 404 not found 找不到内容

表示服务器上无法找到请求的资源。除此之外,也可以在服务器端拒绝请求且不想说明理由时使用。 以下情况会出现404:

  • 404.0 -(无) – 没有找到文件或目录。
  • 404.1 - 无法在所请求的端口上访问 Web 站点。
  • 404.2 - Web 服务扩展锁定策略阻止本请求。
  • 404.3 - MIME 映射策略阻止本请求。
5. 405 禁止使用该方法

表示客户端请求的方法虽然能被服务器识别,但是服务器禁止使用该方法。GET 和 HEAD 方法,服务器应该总是允许客户端进行访问。客户端可以通过 OPTIONS 方法(预检)来查看服务器允许的访问方法。

5. 5xx: 服务器端错误

1. 500 服务器端执行时发生错误

也有可能是 Web 应用存在的 bug 或某些临时的故障。

2. 502 扮演网关或代理角色的服务器有问题

表示扮演网关或代理角色的服务器,从上游服务器中接收到的响应是无效的。注意,502 错误通常不是客户端能够修复的,而是需要由途经的 Web 服务器或者代理服务器对其进行修复。以下情况会出现502:

  • 502.1 - CGI (通用网关接口)应用程序超时。
  • 502.2 - CGI (通用网关接口)应用程序出错。
3. 503 服务器暂时超负载或正在停机维修,现在无法处理请求

如果事先得知解除以上状况需要的时间,最好写入 RetryAfter 首部字段再返回给客户端。

使用场景:

  • 服务器停机维护时,主动用503响应请求;
  • nginx 设置限速,超过限速,会返回503。
4. 504 网关超时

他是HTTP 1.1中新加入的。

使用场景:代码执行时间超时,或者发生了死循环。

13、同样是重定向,302,303,307的区别?

  • 302是,禁止POST变为GET请求,但是使用时仍然使用了;http1.0的协议状态码,在http1.1版本的时候为了细化302状态码又出来了303和307
  • 303是明确表示客户端使用GET方法获取资源,会将POST请求变为GET请求进行重定向。
  • 307是遵照浏览器标准,不会将POST变为GET。

14、HTTP状态码304多点好还是少点好?

服务器为了提高网站网站访问效率,对之前访问的部分页面进行缓存,当客户端再次访问时,服务器端会根据缓存内容判断页面与之前是否一样,若相同返回304,使用缓存,若不同,返回200.

搜索引擎蜘蛛会更加青睐内容更新频繁的网站,通过特定时间内对网站抓取返回的状态码来调节对该网站的抓取频次,若网站一定时间内一直处于304的状态,那么蜘蛛可能会降低对网站的抓取次数。相反,若网站变化的频率非常之快,每次抓取都能获取新的内容,那么回访率也会提高。

产生较多304状态码的原因:

  • 页码更新周期长或不更新
  • 纯静态页面或强制生产静态html

304状态码出现过多会造成一下问题:

  • 网站快照停止
  • 收录减少
  • 权重下降

15、HTTP 1.0 和 HTTP 1.1 之间有哪些区别?

  • 连接方面: http 1.0 默认使用短链接;http 1.1默认使用长连接。通过使用长连接,可使多个http请求复用同一个TCP连接,以此来避免使用短链接时的每次建立。
  • 资源请求方面: http 1.0中存在一些浪费资源的现象,例如客户端只需要某个对象的一部分,而服务器却将整个对象返回,并且不支持断电断续功能;http 1.1中则在请求头引入了range头,它允许只请求资源的某个部分,即返回码是206,这样就方便了开发中自由的选择以便充分利用宽带和连接。
  • 缓存方面: http 1.0时Header头中用if-modified-since,expires作缓存;http 1.1加入了etag/if-none-match等头部缓存。
  • 新增了Host字段: 用来指定服务器的域名。http 1.0中每个服务器对应一个唯一的IP地址,因此请求的url并没有传递主机名;随着虚拟主机的发展,一台服务器可对应多个虚拟主机,并且他们共享一个IP地址,所以有了host字段,这样可以将请求发送到同一台服务器上的不同网站。
  • 新增了很多请求方法: http 1.1新增了很多请求方法,例如PUT,OPTIONS,HEAD等。

16、HTTP 1.1 和 HTTP 2.0 之间有哪些区别?

  • 二进制协议:HTTP/2 是一个二进制协议。在 HTTP/1.1 版中,报文的头信息必须是文本(ASCII 编码),数据体可以是文本,也可以是二进制。HTTP/2 则是一个彻底的二进制协议,头信息和数据体都是二进制,并且统称为"帧",可以分为头信息帧和数据帧。 帧的概念是它实现多路复用的基础。
  • 多路复用: HTTP/2 实现了多路复用,HTTP/2 仍然复用 TCP 连接,但是在一个连接里,客户端和服务器都可以同时发送多个请求或回应,而且不用按照顺序一一发送,这样就避免了"队头堵塞"的问题。
    • 队头阻塞是由 HTTP 基本的“请求 - 应答”模型所导致的。HTTP 规定报文必须是“一发一收”,这就形成了一个先进先出的“串行”队列。队列里的请求是没有优先级的,只有入队的先后顺序,排在最前面的请求会被最优先处理。如果队首的请求因为处理的太慢耽误了时间,那么队列里后面的所有请求需要跟着一起等待,结果就是其他的请求承担了不应有的时间成本,造成了队头堵塞的现象。
  • 数据流: HTTP/2 使用了数据流的概念,因为 HTTP/2 的数据包是不按顺序发送的,同一个连接里面连续的数据包,可能属于不同的请求。因此,必须要对数据包做标记,指出它属于哪个请求。HTTP/2 将每个请求或回应的所有数据包,称为一个数据流。每个数据流都有一个独一无二的编号。数据包发送时,都必须标记数据流 ID ,用来区分它属于哪个数据流。
  • 头信息压缩: HTTP/2 实现了头信息压缩,由于 HTTP 1.1 协议不带状态,每次请求都必须附上所有信息。所以,请求的很多字段都是重复的,比如 Cookie 和 User Agent ,一模一样的内容,每次请求都必须附带,这会浪费很多带宽,也影响速度。HTTP/2 对这一点做了优化,引入了头信息压缩机制。一方面,头信息使用 gzip 或 compress 压缩后再发送;另一方面,客户端和服务器同时维护一张头信息表,所有字段都会存入这个表,生成一个索引号,以后就不发送同样字段了,只发送索引号,这样就能提高速度了。
  • 服务器推送: HTTP/2 允许服务器未经请求,主动向客户端发送资源,这叫做服务器推送。使用服务器推送提前给客户端推送必要的资源,这样就可以相对减少一些延迟时间。这里需要注意的是 http2 下服务器主动推送的是静态资源,和 WebSocket 以及使用 SSE 等方式向客户端发送即时数据的推送是不同的。

17、HTTP 2.0头部压缩算法是怎么样的?

HTTP 2.0的头部压缩是hpack算法。在客户端和服务器端建立“字典”,用引号表示重复的字符串,采用哈夫曼编码来压缩整数和字符串,可以达到50%-90%的高压缩率。

具体来说:

  • 在客户端和服务器端使用“首部表”来跟踪和存储之前发送的键值对,对于相同的数据,不再通过每次请求和响应发送;
  • 首部表在HTTP 2.0的连接存续期内始终存在,由客户端和服务器共同渐进的更新
  • 每次新的首部表键值对要么被追加到当前吧的末尾,要么替换表中之前的值。

18、说一下HTTP 3.0 ?

HPPT 3.0基于UDP协议实现了类似TCP的多路复用数据流,传输可靠性等功能,这套功能被称为QUIC协议。

  • 流量控制,传输可靠性功能: QUIC在UDP的基础上增加了一层来保证数据传输可靠性,它提供了数据包重传,拥塞控制,以及其他一些TCP中的特性。
  • 集成TLS加密功能: 目前QUIC使用TLS1.3,减少了握手所花费的RTT数。
  • 多路复用: 同一物理连接上可以有多个独立的逻辑数据流,实现了数据流的单独传输,解决了TCP的队头阻塞问题。
  • 快速握手: 由于基于UDP,可以实现使用0·1个RTT来建立连接。

image.png

19、HTTP协议的优点和缺点?

HTTP 是超文本传输协议,它定义了客户端和服务器之间交换报文的格式和方式,默认使用 80 端口。它使用 TCP 作为传输层协议,保证了数据传输的可靠性。

优点

  • 支持客户端/服务器模式
  • 简单快速:客户向服务器请求服务时,只需传送请求方法和路径。由于 HTTP 协议简单,使得 HTTP 服务器的程序规模小,因而通信速度很快。
  • 无连接:无连接就是限制每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接,采用这种方式可以节省传输时间。
  • 无状态:HTTP 协议是无状态协议,这里的状态是指通信过程的上下文信息。缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能会导致每次连接传送的数据量增大。另一方面,在服务器不需要先前信息时它的应答就比较快。
  • 灵活:HTTP 允许传输任意类型的数据对象。正在传输的类型由 Content-Type 加以标记。

缺点

  • 无状态: HTTP 是一个无状态的协议,HTTP 服务器不会保存关于客户的任何信息。
  • 明文传输: 协议中的报文使用的是文本形式,这就直接暴露给外界,不安全。
  • 不安全
    • 通信使用明文(不加密),内容可能会被窃听
    • 不验证通信方的身份,因此有可能遭遇伪装
    • 无法证明报文的完整性,所以有可能已遭篡改

20、HTTP协议的性能怎么样?

HTTP协议是基于TCP/IP,并且使用了请求-应答的通信模式,所以性能的关键就在这两点:

1. 长连接

  • HTTP 1.0中使用的短链接,请求-应答完后就会断开连接,下次请求需要再次TCP三次握手,不过可以手动添加Connection:keep-alive来进行长连接
  • HTTP 1.1使用的长连接,减少了TCP连接的重复建立和断开所造成的额外开销,减轻了服务器端的负载。目前对于同一个域,大多数浏览器支持同时建立6个持久连接

image.png

2. 管道网络传输

HTTP/1.1 采用了长连接的方式,这使得管道(pipeline)网络传输成为了可能。

管道(pipeline)网络传输是指:可以在同一个 TCP 连接里面,客户端可以发起多个请求,只要第一个请求发出去了,不必等其回来,就可以发第二个请求出去,可以减少整体的响应时间。但是服务器还是按照顺序回应请求。如果前面的回应特别慢,后面就会有许多请求排队等着。这称为队头堵塞。

  • 队头堵塞

HTTP 规定报文必须是“一发一收”,这就形成了一个先进先出的“串行”队列。队列里的请求是没有优先级的,只有入队的先后顺序,排在最前面的请求会被最优先处理。如果队首的请求因为处理的太慢耽误了时间,那么队列里后面的所有请求需要跟着一起等待,结果就是其他的请求承担了不应有的时间成本,造成了队头堵塞的现象。

  • 队头阻塞的解决方案: (1)并发连接:对于一个域名允许分配多个长连接,那么相当于增加了任务队列,不至于一个队伍的任务阻塞其它所有任务。 (2)域名分片:将域名分出很多二级域名,它们都指向同样的一台服务器,能够并发的长连接数变多,解决了队头阻塞的问题。HTTP2.0的多路复用解决了对头阻塞的问题。

21、URL有哪些部分组成?

例如:baike.baidu.com:8080/item/JavaSc…

  • 协议:有http协议,FTP协议等

  • 域名:该url的域名为baike.baidu.com,也可使用ip地址

  • 端口:例如8080,跟在域名后面的是端口,域名和端口之间使用“:”作为分隔符。端口不是一个URL必须的部分,如果省略端口部分,将采用默认端口(HTTP协议默认端口是80,HTTPS协议默认端口是443);

  • 虚拟目录部分:从域名后的第一个“/”开始到最后一个“/”为止,是虚拟目录部分。虚拟目录也不是一个URL必须的部分。本例中的虚拟目录是“/item/JavaScript/”;

  • 文件名部分:从域名后的最后一个“/”开始到“?”为止,是文件名部分,如果没有“?”,则是从域名后的最后一个“/”开始到“#”为止,是文件部分,如果没有“?”和“#”,那么从域名后的最后一个“/”开始到结束,都是文件名部分。本例中的文件名是“321142”。文件名部分也不是一个URL必须的部分,如果省略该部分,则使用默认的文件名;

  • 锚部分:从“#”开始到最后,都是锚部分。锚部分也不是一个URL必须的部分;

  • 参数部分:从“?”开始到“#”为止之间的部分为参数部分,又称搜索部分、查询部分。本例中的参数部分为“fromtitle=js&fromid=10687961&fr=aladdin”。参数可以允许有多个参数,参数与参数之间用“&”作为分隔符。

22、在浏览器中输入url按下回车后发生了什么?

1. 输入url到页面渲染出来的过程?

(1)解析URL: 首先会对 URL 进行解析,分析所需要使用的传输协议和请求的资源的路径。如果输入的 URL 中的协议或者主机名不合法,将会把地址栏中输入的内容传递给搜索引擎。如果没有问题,浏览器会检查 URL 中是否出现了非法字符,如果存在非法字符,则对非法字符进行转义后再进行下一过程。

(2)缓存判断: 浏览器会判断所请求的资源是否在缓存里,如果请求的资源在缓存里并且没有失效,那么就直接使用,否则向服务器发起新的请求。

(3)DNS解析: 下一步首先需要获取的是输入的 URL 中的域名的 IP 地址

  • 首先会判断本地是否有该域名的 IP 地址的缓存,浏览器查看本地硬盘hosts中是否有缓存,如果有缓存则直接返回ip地址;

  • 如果没有缓存,浏览器请求本地DNS(domain name system域名系统)服务器查看是否有缓存,有缓存返回结果,这个过程是递归的方式查新。本地DNS服务器指的是此网络的服务器商提供,也就是中国移动,中国电信等

  • 没有缓存,本地DNS服务器向根服务器发送请求,根服务器不会给出ip与域名的直接关系,是返回域名服务器地址,这个过程是迭代的过程

  • 本地DNS服务器再向域名服务器发送请求,也不会给出ip与域名的直接关系,而是返回域名的解析服务器地址

  • 本地DNS服务器向域名的解析服务器发送请求,返回ip地址,这时本地DNS服务器会进行缓存,并返回给客户端

(4)获取MAC地址: 当浏览器得到 IP 地址后,数据传输还需要知道目的主机 MAC 地址,

  • 因为应用层下发数据给传输层,TCP 协议会指定源端口号和目的端口号,然后下发给网络层。
  • 网络层会将本机地址作为源地址,获取的 IP 地址作为目的地址。然后将下发给数据链路层,数据链路层的发送需要加入通信双方的 MAC 地址,本机的 MAC 地址作为源 MAC 地址,目的 MAC 地址需要分情况处理。
  • 通过将 IP 地址与本机的子网掩码相与,可以判断是否与请求主机在同一个子网里,如果在同一个子网里,可以使用 APR 协议获取到目的主机的 MAC 地址,如果不在一个子网里,那么请求应该转发给网关,由它代为转发,此时同样可以通过 ARP 协议来获取网关的 MAC 地址,此时目的主机的 MAC 地址应该为网关的地址。

(5)TCP三次握手: 下面是 TCP 建立连接的三次握手的过程

  • 客户端向服务器端发送链接请求,发送SYN=1请求连接,seq = j(随即序号)

  • 服务器端收到客户端发来的请求连接,接受连接的话返回SYN =1,ack = j+1(seq+syn),seq = k

  • 客户端接收服务器的确认应答后,进入连接建立的状态,同时客户端发送ack = k+1到服务器端,服务器端接收到确认后,也进入连接建立状态,此时双方的连接就建立起来了

(6)HTTPS握手: 如果使用的是 HTTPS 协议,在通信前还存在 TLS 的一个四次握手的过程。

  • 首先由客户端向服务器端发送使用的协议的版本号、一个随机数和可以使用的加密方法。

  • 服务器端收到后,确认加密的方法,也向客户端发送一个随机数和自己的数字证书。

  • 客户端收到后,首先检查数字证书是否有效,如果有效,则再生成一个随机数,并使用证书中的公钥对随机数加密,然后发送给服务器端,并且还会提供一个前面所有内容的 hash 值供服务器端检验。

  • 服务器端接收后,使用自己的私钥对数据解密,同时向客户端发送一个前面所有内容的 hash 值供客户端检验。

  • 这个时候双方都有了三个随机数,按照之前所约定的加密方法,使用这三个随机数生成一把秘钥,以后双方通信前,就使用这个秘钥对数据进行加密后再传输。

(7)返回数据: 当页面请求发送到服务器端后,服务器端会返回一个 html 文件作为响应,浏览器接收到响应后,开始对 html 文件进行解析,开始页面的渲染过程。

(8)页面渲染:

  • 浏览器首先会根据 html 文件构建 DOM 树

  • 根据解析到的 css 文件构建 CSSOM 树

  • DOM与CSSOM会合成Render,再进行渲染

  • layout根据render计算好每个节点内容,根据节点正确的显示到浏览器位置

  • Painting根据计算好的绘制页面

(9)TCP四次挥手: 最后一步是 TCP 断开连接的四次挥手过程。

  • 若客户端认为数据发送完成,则它需要向服务端发送连接释放请求。

  • 服务端收到连接释放请求后,会告诉应用层要释放 TCP 链接。然后会发送 ACK 包,并进入 CLOSE_WAIT 状态,此时表明客户端到服务端的连接已经释放,不再接收客户端发的数据了。

  • 但是因为 TCP 连接是双向的,所以服务端仍旧可以发送数据给客户端。服务端如果此时还有没发完的数据会继续发送,完毕后会向客户端发送连接释放请求,然后服务端便进入 LAST-ACK 状态。

  • 客户端收到释放请求后,向服务端发送确认应答,此时客户端进入 TIME-WAIT 状态。该状态会持续 2MSL(最大段生存期,指报文段在网络中生存的时间,超时会被抛弃) 时间,若该时间段内没有服务端的重发请求的话,就进入 CLOSED 状态。

  • 当服务端收到确认应答后,也便进入 CLOSED 状态。

3.jpg

image.png

2. 为何把css放到header中?

从html文件开始加载渲染,等遇到css时,直接渲染成CSSOM,再继续向下,等碰到相应的css就可以直接在CSSOM中查找,走完渲染成DOM树,合成Render,就可以渲染到页面中,

如果放到body最后,等渲染完DOM,遇到css,渲染成CSSOM,然后再去html寻找对应的DOM,再次渲染DOM,就相当于就DOM渲染两次,重复操作

3. 为何把js放到body最后?

如果放到中间或者开始,先加载js,相应等待时间长的话,页面会一直渲染不出来

4. 页面中遇到图片加载缓慢时会等待加载吗?

不会,会根据css留出相应的位置大小,不会等待图片完全加载出来

5. window.onload与DOMContentLoaded?

一般的渲染顺序是:DOMContentLoaded,图片加载出来,onload

window.addEventListener('load',function () {
    //页面全部加载完成后才执行,包括图片和视频
})
document.addEventListener('DOMContentLoaded',function () {
    //DOM加载完即可执行,此时图片和视频可能还没加载完
})

6. 当网页呈现在眼前的过程中,有哪些网页可能出现缓存?

  • 浏览器缓存
  • DNS缓存
  • 服务器缓存
  • cdn静态数据缓存(图片,css)

23、页面有多张图片,HTTP是怎么加载的?

  • HTTP 1下,浏览器对一个域名下最大TCP连接数为6,所以会请求多次。可以用多域名部署解决。这样可以提高同时请求的数目,加快页面图片的获取速度。

  • HTTP 2下,可以一瞬间加载出来很多资源,因为,HTTP2支持多路复用,可以在一个TCP连接中发送多个HTTP请求。