> For the complete documentation index, see [llms.txt](https://anjia1.gitbook.io/web/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://anjia1.gitbook.io/web/browser/qa/network.md).

# 网络相关

1. 从输入 URL 到页面呈现出来的过程
   * [计算机基础 / HTTP / 输入 URL 按下回车之后](https://anjia1.gitbook.io/cs/http/after-enter-url)
2. TCP 的三次握手和四次挥手
   * [计算机基础 / HTTP / TCP 的三次握手](https://anjia1.gitbook.io/cs/http/after-enter-url#1.3-tcp-de-san-ci-wo-shou)
   * [计算机基础 / HTTP / TCP 的四次挥手](https://anjia1.gitbook.io/cs/http/after-enter-url#4.-tcp-de-si-ci-hui-shou)
3. ...

## \~\~\~\~\~\~\~ 基础知识 \~\~\~\~\~\~

<details>

<summary>URL 和 URI 的区别</summary>

URI: Uniform Resource Identifier, 统一资源标识符

* 用唯一的标识来确定一个资源，是一种抽象的定义
* 即不管用什么方法来定义，只要能唯一地标识一个资源，就可以称为 URI

URL 和 URN 是 URI 的子集。

* URL: Uniform Resource Location, 统一资源定位符
  * 可以理解为使用地址来标识资源
* URN: Uniform Resource Name, 统一资源名称

</details>

<details>

<summary>跨域</summary>

1. 同源 vs 跨域
   * origin: 协议+域名+端口
2. 同源策略的限制 （???）
   * cookie, localStorage, IndexDB 无法读取
   * DOM 和 JS 对象无法获得
   * AJAX 请求不能发送
3. 跨域解决方案
   * JSONP, postMessage
   * CORS
   * document.domain
   * ....

P20

跨域，是指浏览器不能执行其它网站的脚本。它是由浏览器的同源策略造成的，是浏览器对 JavaScript 实施的安全限制，那么只要协议、域名、端口有任何一个不同，都被当作是不同的域。 跨域原理，即是通过各种方式，避开浏览器的安全限制。

JS 实现跨域的方法，<https://segmentfault.com/a/1190000011145364>

</details>

<details>

<summary>JSONP</summary>

JSONP 能实现跨域，它是利用标签不受同源策略限制的特性（这算是一个漏洞）。

1. 浏览器用 JavaScript 代码动态创建一个 `<script>` 标签，其 `src` 属性引用第三方的 API 地址，并提供一个回调函数的 function name
   * 比如 <https://www.smartstudy.com/api/?callback=functionName>
   * 其中的 query 都是约定好了，比如 `callback` 和 `functionName`
2. 后端通过 query 取到函数名，然后把需要的数据以参数的形式传递给该函数，返回给浏览器
3. 浏览器解析服务器返回的数据，执行该回调函数

JSONP 并不使用 XMLHttpRequest 对象加载数据，而是通过 `<script>` 标签把资源当做普通的 JavaScript 脚本来加载，所以不存在跨域的问题，也不是真正的 AJAX。

</details>

<details>

<summary>CORS vs JSONP</summary>

CORS 可以用作 JSONP 模式的现代替代方案：

* JSONP 仅支持 GET 方法，而 CORS 还支持其它类型的 HTTP 请求
* CORS 让程序员可以使用常规的 XMLHttpRequest，它支持比 JSONP 更好的错误处理
* JSONP 可能会导致跨站点脚本 XSS 问题（在外部站点受到威胁时），而 CORS 允许网站手动解析响应以提高安全性

JSONP 的主要优点是兼容 CORS 出现之前的老版浏览器。现在大多数现代 Web 浏览器都支持 CORS。

</details>

<details>

<summary>客户端存储</summary>

cookie, sessionStorage, localStorage, indexdDB

共同点：都保存在浏览器端，且都是同源的

1. 是否在 HTTP 中携带
   1. cookie 数据会始终在同源的 HTTP 请求中携带（即使不需要），即在浏览器和服务器之间来回传递
      * 所以它的容量较小，大约 4K 左右
      * 所以只适合保存很小的数据，比如会话标识
      * 初衷就是为了弥补 HTTP 的无状态
   2. sessionStorage 和 localStorage 仅在本地保存，不参与和服务器的通信
2. 是否持久化保存
   1. cookie：在设置的 cookie 过期时间之前一直有效（即使窗口或浏览器关闭了），否则默认为关闭浏览器后失效
      * cookie 还可以限制只属于某个 path 下
   2. sessionStorage：仅在当前“浏览器”窗口关闭前有效（不持久）
      * session，会话，两个页签打开同一个页面，也被视为同一个会话
   3. localStorage：持久化存储（即使窗口或浏览器关闭了），除非被手动清除
3. 存储空间
   1. cookie，4K 左右
   2. sessionstorage 和 localStorage，5M 左右
4. 易用性
   1. cookie 原生的接口不太友好，需要自己封装
   2. 其它：可采用原生接口，也可自己封装
5. 应用场景
   1. cookie

</details>

<details>

<summary>Web 性能优化</summary>

检测页面的加载时间，一般有两种方式：

1. 被动去测：在被检测的页面置入脚本或探针，当用户访问网页时，探针自动采集数据并传回数据库进行分析（数据更真实）
2. 主动监测：主动搭建分布式受控环境，模拟用户发起页面访问请求，主动采集性能数据并分析。在检测的精准度上，专业的第三方工具效果更佳，比如说性能极客

优化手段：

1. 内存溢出
2. 降低请求量：合并资源，减少 HTTP 请求数，minify/gzip 压缩，webP，lazyLoad
3. 加快请求速度：预解析 DNS，减少域名数，并行加载，CDN 分发，避免重定向
4. 缓存：HTTP 协议缓存请求，离线缓存 manifest，离线数据缓存 localStorage
5. 渲染：JS/CSS 优化，动画绘制频率，加载顺序，服务端渲染，pipeline

</details>

<details>

<summary>&#x3C;script> 的 async 和 sync</summary>

</details>

## \~\~\~\~\~\~ HTTP 相关 \~\~\~\~\~

<details>

<summary>HTTP 请求的方法</summary>

最常见：

1. `GET` 从指定的资源请求数据
2. `POST` 向指定的资源提交要被处理的数据

次常见：

1. `HEAD`：类似于 GET 请求，只是返回的响应中没有具体内容，客户端读取响应的 Headers
2. `OPTIONS`：允许客户端查看服务器的性能，比如服务器支持的请求方式等

不太常见的：

1. `PUT`
2. `DELETE`
3. `TRACE`
4. `CONNECT`

</details>

<details>

<summary>get 和 post 的区别</summary>

GET <mark style="background-color:blue;">vs</mark> POST

1. 参数位置：在 URL 里 <mark style="background-color:blue;">vs</mark> 在 request body 中
   * 只能 URL 编码 <mark style="background-color:blue;">vs</mark> 多种编码方式
   * GET 的参数有长度限制，而 POST 没有
     * 一般限制在 2\~8K 之间，常见的是 1K 之内
   * POST 的参数更安全，所以更适合传递一些敏感信息
2. 浏览器的不同处理
   * GET 请求会被浏览器主动 cache
   * GET 请求参数会被完整地保留在浏览历史记录里
3. TCP 数据包
   * GET 请求产生一个 TCP 数据包
     * 浏览器会把 HTTP Header 和 data 一起发出去，服务器响应 200
   * POST 产生两个 TCP 数据包
     * 浏览器先发送 header，服务器响应 100 continue
     * 浏览器再发送 data，服务器响应 200 ok

GET 和 POST 的底层都是 TCP/IP，都是 TCP 连接，并无差别。只是由于 HTTP 的规定以及浏览器和服务器的限制，导致它们在使用上有些不同。

</details>

<details>

<summary>get 请求传参长度的误区</summary>

误区：我们常说 get 请求参数的大小存在限制，而 post 请求的参数大小是无限制的。

* HTTP 协议从未规定 get 和 post 请求的长度限制
* 而是浏览器和 web 服务器限制了 get 请求的参数长度
* 不同的浏览器和 web 服务器，限制的最大长度不一样
  * 要支持 IE，则最大长度为 2083byte
  * 若只支持 Chrome，则最大长度 8182byte

</details>

<details>

<summary>HTTP 返回的状态码</summary>

</details>

<details>

<summary>HTTP Header</summary>

可以将 HTTP Header 分为：

1. 通用首部：表示一些通用信息。比如：
   * `date` 表示报文创建时间
2. 请求首部：请求报文中独有的。比如：
   * cookie 相关的 `if-Modified-Since`
3. 响应首部：响应报文中独有的。比如：
   * `set-cookie`
   * `location` 重定向相关
4. 实体首部：用来描述实体部分。比如：
   * `allow` 用来描述可执行的请求方法
   * `content-type` 描述主题类型
   * `content-Encoding` 描述主体的编码方式

</details>

<details>

<summary>一个 TCP 连接能发几个 HTTP 请求？</summary>

1. HTTP 1.0，一个 TCP 发送一个 HTTP 请求
   * 一般情况，不支持长连接，在每次请求发送完毕之后 TCP 连接会立即断开
   * 在请求头带上 `Connection: Keep-Alive` 也可以发送多条，不过有限制
2. HTTP 1.1，支持长连接，所以只要 TCP 连接不断开，就可以一直发送 HTTP 请求，没有上限
3. HTTP 2.0
   * 支持长连接。所以只要 TCP 连接不断开，就可以一直发送 HTTP 请求，没有上线
   * 支持多路复用，所以一个 TCP 连接可以并发多个 HTTP 请求

</details>

<details>

<summary>TCP 和 UDP</summary>

TCP 是面向连接的可靠性传输，而 UDP 是不可靠的。

TCP <mark style="background-color:blue;">vs</mark> UDP

1. 面向连接的 <mark style="background-color:blue;">vs</mark> 无连接的（发送数据前不需要先建立链接）
2. 提供可靠服务 <mark style="background-color:blue;">vs</mark> 尽最大努力交付（不保证可靠交付）
   * 通过 TCP 连接传送的数据，无差错、不丢失、不重复、且按序到达
   * UDP 即便出现网络拥塞也不会降低发送速率，所以会丢包
     * 比如实时应用（电话和视频会议）
3. 面向字节流 <mark style="background-color:blue;">vs</mark> 面向报文
4. 只能是 1 对 1 的 <mark style="background-color:blue;">vs</mark> 支持 1 对 1, 1 对多
5. 首部大小：20 字节 <mark style="background-color:blue;">vs</mark> 只有 8 字节

</details>

<details>

<summary>WebSocket 的实现和应用</summary>

WebSocket 是 HTML5 中的协议，支持持久性连接。

* HTTP 1.0 和 HTTP 1.1 都不支持持久性的连接
* HTTP 1.1 中的 `keep-alive` 可以将多个 HTTP 请求合并为一个。

HTTP 的生命周期通过 Request-Response 来界定。一个 Request 只能对应一个 Response，而且这个 Response 是被动的，不能主动发起。

* 在 HTTP 1.0 协议中，这次 HTTP 请求就结束了
* 在 HTTP 1.1 中，`connection: Keep-alive`，就可以在一个 HTTP 连接中，发送多个 Request，接收多个 Response

WebSocket 是基于 HTTP 协议的，或者说借用了 HTTP 协议来完成一部分握手，在握手阶段和 HTTP 是相同的。

看一个 websocket 握手协议的实现，基本是 2 个属性 `upgrade`, `connection`。

```
GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw== 
Sec-WebSocket-Protocol: chat, superchat 
Sec-WebSocket-Version: 13
Origin: http://example.com
```

</details>

<details>

<summary>websocket 和 ajax 轮询</summary>

* websocket，HTML5 的新协议，可以实现服务端和服务器的通信，实现服务器的推送功能
  * 优点：只要建立一次连接，就可以连续不断地得到服务器推送的消息，因此节省带宽、减少服务器端的压力
* ajax 轮询：每隔一段时间（0.5s）就向服务器发起 ajax 请求，以查询服务器是否有数据更新
  * 缺点：每次都要建立 HTTP 连接，因此比较浪费带

</details>

<details>

<summary>HTTP 协议（特征）</summary>

* 基于 TCP/IP 通信协议来传递数据，比如 HTML 文件、图片文件、查询结果
* 属于应用层的、面向对象的协议
* 使用简捷、快速，适用于分布式超媒体信息系统
  * 它于 1990 年提出，经过几年的使用与发展，得到不断地完善和扩展
  * 目前在 WWW 中使用的是 HTTP/1.0 的第六版
  * HTTP/1.1 的规范化工作正在进行之中
  * HTTP-NG(Next Generation of HTTP)的建议已经提出
* HTTP 协议工作于客户端-服务端架构中
  * 浏览器作为 HTTP 客户端，通过 URL 向 HTTP 服务端（WEB 服务器）发送请求
  * Web 服务器根据接收到的请求后，向客户端发送响应信息

</details>

<details>

<summary>HTTP 和 HTTPS 的区别</summary>

HTTP，超文本传输协议。基于 TCP/IP 通信协议，用于从 WWW 服务器传输超文本到本地浏览器，它的模式是“一个请求对应一个响应”。

HTTPS 是 HTTP 的安全版，即在 HTTP 下加入 SSL 层。SSL 是 HTTPS 的安全基础，因为 HTTP 传输的数据是明文的（没有加密），而 SSL 协议可以对其数据进行加密。SSL 加密是在传输层实现的。

所以说，HTTPS 比 HTTP 协议的安全性更高，它能进行加密传输和身份认证。

* SSL 加密
* CA 证书

此外，HTTP 80端口 <mark style="background-color:blue;">vs</mark> HTTPS 443端口

</details>

<details>

<summary>HTTPS 的原理和优缺点</summary>

#### 工作原理

* 客户端使用 HTTPS URL 访问服务器
* 服务器建立 SSL 链接，并将网站的证书（包含了公钥）传给客户端
* 客户端和服务器端开始协商 SSL 链接的安全等级，并建立会话密钥
* 然后通过网站的公钥来加密会话密钥并传送给网站

#### 优点

* 可以认证用户和服务器，确保数据发送到正确的客户机和服务器
* 更安全，可防止数据在传输过程中被窃取、改变
* 是现行架构下最安全的解决方案，虽然不是绝对安全，但它大幅增加了中间人攻击的成本

#### 缺点

* 握手阶段比较费时，会使页面加载时间延长 50%，增加 10%\~20%的耗电
* 缓存不如 HTTP 高效，会增加数据开销
* SSL 证书需要钱，功能越强大的证书费用越高
* SSL 证书需要绑定 IP，不能在同一个 IP 上绑定多个域名，ipv4 资源支持不了这种消耗

</details>

<details>

<summary>HTTP 2.0</summary>

HTTP 2.0 是基于 HTTPS 的，天然具有安全特性，且它还能避免单纯使用 HTTPS 的性能下降。

1. 提升访问速度：HTTP 1.0，请求资源所需时间更少、访问速度更快
2. 多路复用：这相当于是长连接的增强
   * 每个 Request 请求可以随机地混杂在一起，接收方可以根据 Request 的 id 将 Request 再归属到各自不同的服务端请求里面
   * 另外多路复用中也支持了流的优先级，允许客户端告诉服务器那些内容是更优先级的资源，可以优先传输。
   * 在 HTTP 1.1 中，客户端在同一时间针对同一域名下的请求，有数量限制（连接数量），超过限制了会被阻塞
3. 二进制分帧：
   * HTTP 1.X 的解析是基于文本的
   * HTTP 2.0 将所有的传输信息分割为更小的消息和帧，并对它们采用二进制格式编码
   * 基于二进制可以让协议有更多的扩展性，比如用“帧”来传输数据和指令
4. 首部压缩
5. 服务器端推送

</details>

<details>

<summary>cookie, session 区别</summary>

* HTTP 是一个无状态协议，cookie 的最大作用就是存储
* sessionId 用来唯一标识用户

cookie 和 session 都可以用来存储用户信息。

1. 位置不同
   * cookie 存放在客户端（约4K），服务端和客户端都可以设置
   * session 存放在服务器端，可以存文件/数据库/内存中
2. 安全性：cookie < session
   * 可以通过分析存放在本地的 cookie 并进行 cookie 欺骗，不安全
   * 敏感信息通常用 session 存储，比如用户登录信息
3. 性能：cookie > session
   * session 会在一定时间内保存在服务器上，当访问增多，会比较占用服务器的性能
4. 存储大小
   * 单个 cookie 保存的数据不能超过 4K，很多浏览器都限制一个站点最多保存 20 个 cookie

</details>

## \~\~\~\~\~\~\~\~ 缓存 \~\~\~\~\~\~\~\~

<details>

<summary>缓存机制的 4 个方面</summary>

作用：减少网络 IO 消耗，提高访问速度。

浏览器的缓存机制有四个方面，按照获取资源时请求的优先级，依次排列如下：

1. Memory Cache
2. Service Worker Cache
3. HTTP Cache
4. Push Cache

</details>

<details>

<summary>强缓存、协商缓存</summary>

根据响应的 Header 内容来决定：

1. 强缓存：`200` from cache，不发请求到服务器，直接从缓存取
   * 过去用 `expires`，使用的是基于服务器端的绝对时间（会存在时差）
   * 现在用 `Cache-Control`，使用相对时间
     * 是一个通用 Header 字段，可用于 HTTP 请求和响应中
     * 该缓存指令是单向的，常见的取值有
       * `private` 默认
       * `no-cache`
       * `max-age`
       * `must-revalidate`
   * 若两同时存在，则用新的
2. 协商缓存：`304` not modified，发送请求到服务器，通过服务器告知缓存是否可用
   * `Last-Modified` 时间戳
   * `Last-Modified/If-Modified-Since`
   * `Etag/If-None-Match`

在没有命中强缓存的时候，才会走协商缓存。

预期：如果服务器上的资源更新了，那浏览器就请求新资源；否则就用本地缓存。以最大程度地减少因网络请求而产生的资源浪费。

![](/files/OmxFZqwN6PI6JMIXn0cd)

![](/files/M1v2oVACDS460XaynlsW)

在请求这些有设置缓存的数据时，会先查看是否过期

* 如果没有过期，则直接使用本地缓存
* 否则，就向服务器发起请求，并重新协商有关缓存信息
  * 如果上次响应设置了 `ETag` 值，则会在这次请求的时候作为 `If-None-Match` 的值交给服务器校验
  * 如果上次响应设置了 `Last-Modified` 值，则会在这次请求的时候作为 `If-Modified-Since` 的值交给服务器校验
  * 如果都没有设置，则直接请求
* 而在需要“服务器校验（协商缓存）”时，它会返回 `200` 或 `304`
  * `200` 表示这是全新的数据
  * `304` 表示从缓存取

说明：两次“从缓存取”，第一次是命中强缓存，第二次是经过与服务器协商且确认缓存未过期。

详情参阅：<https://segmentfault.com/a/1190000008956069>

</details>

<details>

<summary>get 和 post 请求在缓存方面的区别</summary>

缓存一般只适用于那些“不会更新服务端数据”的请求。所以：

* 一般会对 get 请求进行缓存
* 很少会对 post 请求进行缓存

</details>

<details>

<summary>cookie 的编码方式</summary>

`encodeURI()`

</details>

<details>

<summary>cookie 可以设置的字段</summary>

1. `name` cookie 的名称
2. `value` cookie 的值
3. `domain` 为可以访问此 cookie 的域名
   * 顶级域名
     * 只能设置 `domain` 为顶级域名，不能设置为二级域名或者三级域名，否则 cookie 无法生成
     * 只能获取到 `domain` 设置为顶级域名的 cookie，其他 domain 设置为二级域名的无法获取
   * 二级域名能读取设置了 `domain` 为顶级域名或者自身的 cookie，但不能读取其他二级域名 `domain` 的 cookie
     * 所以要想 cookie 在多个二级域名中共享，需要设置 domain 为顶级域名，这样就可以在所有二级域名里面或者到这个 cookie 的值了
   * 非顶级域名（如二级域名或者三级域名）设置的 cookie 的 `domain` 只能为顶级域名或二级域名或三级域名本身，不能设置其他二级域名的 cookie，否则 cookie 无法生成
4. `path` 为可以访问此 cookie 的页面路径
   * 比如 domain 是 abc.com,path 是/test，那么只 有/test 路径下的页面可以读取此 cookie。
5. `expires/Max-Age` 为此 cookie 过期时间
   * 若设置其值为一个时间，那么当到达此时间后，此 cookie 失效
   * 不设置的话默认值是 Session，意思是 cookie 会和 session 一起失效。当浏览器关闭(不是浏览器标签页，而是整个浏览器) 后，此 cookie 失效
6. `Size` 此 cookie 大小
7. `http` cookie 的 `httponly` 属性
   * 若此属性为 true，则只有在 HTTP 请求头中会带有此 cookie 的信息，而不能通过 `document.cookie` 来访问此 cookie。
8. `secure` 设置是否只能通过 HTTPS 来传递此条 cookie

</details>

<details>

<summary>cookie 的弊端</summary>

1. 安全性
   * 若被拦截了，就能得到相关的 session 信息
   * 甚至不需要解密，原样转发就能达到目的
2. 有数量和长度的限制
   * 每个 domain 最多 20 条 cookie
   * 每个 cookie 最大长度 4KB
3. 场景有限。比如

</details>

<details>

<summary>ajax 解决浏览器缓存问题</summary>

1. 在 ajax 发送请求前加上 `anyAjaxObj.setRequestHeader("If-Modified-Since","0")`&#x20;
2. 在 ajax 发送请求前加上 `anyAjaxObj.setRequestHeader("Cache-Control","no-cache")`&#x20;
3. 在 URL 后面加上一个随机数: `"fresh=" + Math.random()`&#x20;
4. 在 URL 后面加上时间戳 `"nowtime=" + new Date().getTime()`

如果是使用 jQuery，直接这样就可以了 `$.ajaxSetup({cache:false})`，这样页面的所有 ajax 都会执行这条语句就是不需要保存缓存记录。

</details>

## \~\~\~\~\~\~\~\~ 更多 \~\~\~\~\~\~\~\~

<details>

<summary>Fetch 发送两次请求的原因</summary>

Fetch 发送 POST 请求时，总是发送两次：第一次状态码是 204，第二次才成功。

原因：Fetch 第一次会发送一个 Options 请求，询问服务器是否支持修改的请求头，如果服务器支持，则会在第二次发送真正的请求

</details>

<details>

<summary>CDN</summary>

CDN，Content Delivery Network，内容分发网络。

CDN 是一个智能虚拟网络，构建在现有网络的基础之上的。它依靠部署在各地的边缘服务器，通过中心平台的负载均衡、内容分发、调度等功能模块，让用户就近获取所需内容，从而降低网络阻塞、提高用户访问响应速度和命中率。CDN 的关键技术主要：内容存储和分发技术。

CDN 的主要功能：

1. 节省骨干网带宽，减少带宽请求量
2. 提供服务器端加速，避免由于用户访问量大而造成服务器过载
3. 服务商使用 web cach 技术，在本地缓存“用户访问过的 web 页面和对象”
   * 既避免了占用主干的出口带宽
   * 又能缩短用户访问页面的响应时间
4. 能克服网站分布不均的问题，并且能降低网站自身建设和维护成本
5. 降低“通信风暴”的影响，从而提高网络访问的稳定性

CDN 的基本原理是：广泛采用各种缓存服务器，将这些缓存服务器分布到用户访问相对集中的地区或网络中，在用户访问网站的时候，利用“全局负载技术”将用户的访问指向距离最近、且工作正常的缓存服务器上，由缓存服务器直接响应用户的请求。

</details>

<details>

<summary>图片的懒加载和预加载</summary>

* 预加载：提前加载图片，当用户需要查看时可直接从本地缓存中渲染
* 懒加载：迟缓加载，减少请求数或延迟请求数，主要是作为服务器端的优化

</details>

<details>

<summary>访问图片 URL 后直接下载，如何实现？</summary>

在请求的返回头里，用于浏览器解析的重要参数就是 OSS 的 API 文档里面的返回 HTTP 头，决定用户下载行为的参数。

```
x-oss-object-type: Normal
x-oss-request-id: 598D5ED34F29D01FE2925F41
x-oss-storage-class: Standard
```

</details>


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://anjia1.gitbook.io/web/browser/qa/network.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
