No118.精选前端面试题,享受每天的挑战和学习

文章目录

    • 为什么说HTTP是无状态的协议?
    • [HTTP 报文结构是怎样的?](#HTTP 报文结构是怎样的?)
    • [HTTP1.1 中如何解决 HTTP 的队头阻塞问题?](#HTTP1.1 中如何解决 HTTP 的队头阻塞问题?)
    • [HTTP 中如何处理表单数据的提交?](#HTTP 中如何处理表单数据的提交?)
    • [说下application/x-www-form-urlencoded 和 multipart/form-data](#说下application/x-www-form-urlencoded 和 multipart/form-data)
    • [对于定长和不定长的数据,HTTP 是怎么传输的?](#对于定长和不定长的数据,HTTP 是怎么传输的?)

为什么说HTTP是无状态的协议?

HTTP 被称为无状态协议,是因为它在不同的请求之间并不保留任何状态信息。每个 HTTP 请求和响应都是独立的,服务器不会记住之前的请求或会话信息。

这是由于 HTTP 的无连接性的特性所决定的。每当客户端发送一个请求给服务器,服务器会根据请求进行处理并发送响应,完成后立即断开连接。在下一个请求中,服务器无法知道上一个请求的信息,也无法获取客户端的状态。

为了维护应用程序或用户状态,通常会使用一些机制实现会话管理,比如使用 Cookie 或者在请求中使用特定的标识符来标记用户会话。这样服务器可以根据这些标识符来识别用户和会话状态。

尽管 HTTP 是无状态的协议,但通过使用会话管理等技术,可以实现状态的保持和管理,使得 HTTP 在实际应用中能够处理复杂的交互和用户认证等需求。

HTTP 报文结构是怎样的?

HTTP 报文结构分为请求报文和响应报文两种类型。

请求报文的结构:

<方法> <请求目标> <HTTP 版本>
<请求头字段 1>: <值 1>
<请求头字段 2>: <值 2>
...
<空行>
<请求主体>

其中,<方法> 表示请求方法(例如 GET、POST、PUT 等),<请求目标> 表示请求的目标 URL,<HTTP 版本> 表示使用的 HTTP 版本号。请求头字段和值由一行一行组成,在空行之前。请求主体是可选的,用于包含请求的数据。

响应报文的结构:

<HTTP 版本> <状态码> <原因短语>
<响应头字段 1>: <值 1>
<响应头字段 2>: <值 2>
...
<空行>
<响应主体>

其中,<HTTP 版本> 表示响应所使用的 HTTP 版本号,<状态码> 表示服务器对请求的处理结果,<原因短语> 是对状态码的简要描述。响应头字段和值由一行一行组成,在空行之前。响应主体也是可选的,用于包含响应的数据。

请求报文和响应报文都采用了 ASCII 文本格式,通过 CRLF(回车换行)来分隔行,空行用于分隔头部和主体。这种简单的结构使得 HTTP 报文易于解析和组装。

HTTP1.1 中如何解决 HTTP 的队头阻塞问题?

在HTTP/1.1中,队头阻塞(Head-of-Line Blocking)是指在一个TCP连接上的请求和响应是按照顺序进行的,如果前面的请求由于某种原因被阻塞,那么后面的请求也会受到影响,导致整体性能下降。

为了解决HTTP的队头阻塞问题,可以采取以下策略:

  1. 使用多个域名:在一个页面中使用多个域名,每个域名对应一个TCP连接,这样可以提高并行度。
  2. 域名分片(Domain Sharding):将一个域名下的资源分解为多个子域名,使得浏览器能够同时并行请求多个资源。
  3. 链接重用 :通过在HTTP头中添加Connection: keep-alive字段,保持TCP连接的持久性,避免重复建立和关闭连接的开销。
  4. 分块传输(Chunked Transfer Encoding):可以将响应分割为多个部分进行传输,使得前面的响应可以提前发送给客户端。
  5. 压缩传输 :在请求头中添加Accept-Encoding字段,支持服务器对响应进行压缩,减小传输内容大小,提高传输速度。

需要注意的是,尽管这些策略可以减轻HTTP的队头阻塞问题,但并不能完全解决 。HTTP/2和HTTP/3协议在协议层面上引入了新的特性,如多路复用、头部压缩等,更好地解决了队头阻塞问题。因此,在新的项目中优先考虑使用HTTP/2或HTTP/3以获取更好的性能表现。

HTTP 中如何处理表单数据的提交?

c 复制代码
在 http 中,有两种主要的表单提交的方式,体现在两种不同的Content-Type取值:

application/x-www-form-urlencoded
multipart/form-data
由于表单提交一般是POST请求,很少考虑GET,因此这里我们将默认提交的数据放在请求体中。

在 HTTP 中,表单数据的提交通常使用 POST 请求来完成。有几种常见的方式来提交表单数据:

  1. 表单的 method 属性设置为 post,并将表单的 action 属性指向接收表单数据的服务端接口。提交表单时,浏览器会按照表单字段的名称和值构建一个键值对的数据结构,并将其作为请求体发送给服务端。

  2. 使用 AJAX 技术提交表单数据。可以使用库或原生 JavaScript 的 XMLHttpRequest 对象来发送 POST 请求,将表单字段构建的键值对数据作为请求体发送到服务端。

  3. 使用 Fetch API 来发送 POST 请求。可以使用 fetch 函数发送 POST 请求,并将表单字段构建的键值对数据作为请求体发送给服务端。

无论使用何种方式,服务端都需要接收请求,并解析请求体中的表单数据。服务端可以使用各种编程语言和框架来解析表单数据,常用的包括 PHP 的 $_POST 变量、Java 的 Servlet、Node.js 的 Express 等。

需要注意的是,为了防止跨站请求伪造(CSRF)攻击,通常需要在表单中添加一个令牌(CSRF token),并在服务端验证该令牌的有效性。这可以防止来自其他网站的恶意请求。

总而言之,表单数据的提交是通过发送 POST 请求,并将表单字段构建的键值对数据作为请求体发送给服务端来实现的。

说下application/x-www-form-urlencoded 和 multipart/form-data

application/x-www-form-urlencodedmultipart/form-data 是两种常见的用于在 HTTP 请求中传输表单数据的 Content-Type。

  1. application/x-www-form-urlencoded
c 复制代码
其中的数据会被编码成以&分隔的键值对
字符以URL编码方式编码。

这是默认的表单提交方式。在这种格式下,表单数据被编码为键值对的格式,并使用 & 符号分隔。字段名和字段值都需要进行 URL 编码,即对特殊字符进行替换。例如,一个含有两个字段的表单:

name=John+Doe&age=30

这种格式适合简单的表单数据,并且数据量较小。

  1. multipart/form-data
c 复制代码
请求头中的 Content-Type 字段会包含 boundary ,且 boundary 的值有浏览器默认指定。
例: Content-Type: multipart/form-data;boundary=----WebkitFormBoundaryRRJKeWfHPGrS4LKe。

数据会分为多个部分,每两个部分之间通过分隔符来分隔,每部分表述均有 HTTP 头部描述子包体,
如Content-Type,在最后的分隔符会加上--表示结束。

这种格式适用于上传文件或提交包含大量字段和较大数据量的表单 。在这种格式下,表单数据被划分为多个部分,每个部分对应一个字段或文件。每个部分都有一个自己的头部信息,包含字段名、文件名等。每个部分以 boundary 分隔符作为边界,不同字段的数据之间使用 boundary 进行划分。一般情况下,在请求头中会包含 Content-Type: multipart/form-data; boundary=xxxxx,其中 xxxxx 是一个随机生成的字符串。

这种格式在数据传输时比较灵活,可以支持多个文件上传、二进制数据等。但由于每个部分都需要有自己的头部信息,所以相对于 application/x-www-form-urlencoded 格式会产生更多的额外数据量。

需要根据具体的需求选择合适的格式。如果只是简单的表单数据提交,可以使用 application/x-www-form-urlencoded。如果需要上传文件或传输大量的字段和数据,那么就需要使用 multipart/form-data 格式。

对于定长和不定长的数据,HTTP 是怎么传输的?

对于定长数据,HTTP 使用 Content-Length 头字段来指定消息体的长度。服务器在发送响应时会包含 Content-Length 头字段,客户端在接收响应时会根据这个长度来准确地读取响应的内容。

对于不定长数据,HTTP 使用 Transfer-Encoding 头字段来指定传输编码。常见的传输编码有 chunked 编码和 gzip 编码。在 chunked 编码中,响应的消息体被分割为多个块,每个块都包含一个长度前缀和实际的数据,最后一个块的长度为0。这样,客户端在接收响应时可以逐块读取数据,而不需要等到整个消息体都传输完毕。

对于 gzip 编码,服务器会对响应的消息体进行压缩,然后将压缩后的数据通过流式传输发送给客户端。客户端接收到压缩后的数据后,会对其进行解压缩,得到原始的消息体。

不论是定长数据还是不定长数据,HTTP 都是通过 TCP 连接进行传输的。

相关推荐
蜡笔小新星14 分钟前
Python Kivy库学习路线
开发语言·网络·经验分享·python·学习
zqx_716 分钟前
随记 前端框架React的初步认识
前端·react.js·前端框架
攸攸太上28 分钟前
JMeter学习
java·后端·学习·jmeter·微服务
惜.己33 分钟前
javaScript基础(8个案例+代码+效果图)
开发语言·前端·javascript·vscode·css3·html5
什么鬼昵称1 小时前
Pikachu-csrf-CSRF(get)
前端·csrf
Ljubim.te1 小时前
Linux基于CentOS学习【进程状态】【进程优先级】【调度与切换】【进程挂起】【进程饥饿】
linux·学习·centos
长天一色1 小时前
【ECMAScript 从入门到进阶教程】第三部分:高级主题(高级函数与范式,元编程,正则表达式,性能优化)
服务器·开发语言·前端·javascript·性能优化·ecmascript
yngsqq1 小时前
031集——文本文件按空格分行——C#学习笔记
笔记·学习·c#
NiNg_1_2342 小时前
npm、yarn、pnpm之间的区别
前端·npm·node.js
秋殇与星河2 小时前
CSS总结
前端·css