网页请求接口规范 0.1.0
本包让浏览器里的豫言应用向本站(同源)发起 HTTP 请求并读取文字响应。它是 fetch 的最小公共子集,为豫言的单事件循环而设计:发起请求不阻塞——发起网页请求 立即返回请求号,请求在后台进行,结束时宿主向统一事件队列(见[网页事件接口规范](../网页事件/规范.汉语.md))投递一个类型为“请求”的事件;多个请求可以同时在途,应用继续处理界面事件,也可以随时 取消网页请求。为方便简单场景另附阻塞变体 请求网页文字。应用依赖本包后,全部函数都必须实现。
出站到其他来源的请求、服务端的出站请求分别属于[网络](../网络/规范.汉语.md)(整体请求响应,暂无浏览器适配)与网页上游、授权服务等包,不在本包。
请求 JSON
发起网页请求、请求网页文字 的参数是 JSON 对象,只有 `网址` 必填,其余可省;出现未知字段或类型不对一律抛事故。
| 字段 | 类型与默认 | 规则 |
| --- | --- | --- |
| 网址 | 文字,必填 | 以 / 开头(不以 // 开头)的站内路径,或与当前页面同源的绝对网址;至多 8192 个 UTF-16 码元;不含控制字符与反斜杠。片段(#…)被忽略 |
| 方法 | 文字,默认 GET | 只能是 GET、HEAD、POST、PUT、PATCH、DELETE(大写) |
| 标头 | 对象,默认无 | 名称→文字值;至多 32 项;名称 1 至 64 个 ASCII 字母、数字、连字符;值至多 4096 个 UTF-16 码元且不含控制字符;宿主拒绝 fetch 规范的禁用标头名(Cookie、Host、Content-Length、Origin、Referer、User-Agent、Connection、Transfer-Encoding、Upgrade、Via、Accept-Encoding、Date、Expect 以及 Sec-、Proxy- 前缀) |
| 正文 | 文字,默认无 | 请求正文,按 UTF-8 发送;至多 8 MiB(UTF-8 字节);GET、HEAD 带正文属违规。带 正文 而 标头 里没有 Content-Type 时宿主不加默认值,应用应自己写(例如 application/json) |
| 缓存 | 文字,默认 默认 | 默认 用浏览器默认缓存策略;不缓存 等价于 cache: 'no-store' |
| 超时毫秒 | 整数,默认 60000 | 1 至 600000;从发出到读完正文的总时限 |
| 正文上限 | 整数,默认 8388608 | 1 至 16777216(字节);响应正文超过此值即中止并报“正文过大” |
| 标记 | 文字,默认空 | 至多 256 个 UTF-16 码元;原样出现在响应里,供应用配对请求 |
宿主固定使用 credentials: 'same-origin'(带本站的饼)与 mode: 'same-origin'(重定向到别的来源即视为网络错误),跟随同源重定向。请求 JSON 整体至多 10 MiB。
响应 JSON
事件详情与阻塞变体的返回值是同一种对象:
{"成":true,"状态":200,"状态文":"OK","网址":"https://例.站/cloud/api/session",
"标头":{"content-type":"application/json","cache-control":"no-store"},
"正文":"{\"user\":…}","字节数":1234,"标记":"会话"}
{"成":false,"原因":"超时","说明":"请求超过 60000 毫秒未完成","标记":"会话"}
- 成为真:收到了 HTTP 响应并读完正文;任何状态码(含 4xx、5xx)都是“成”,应用自行判断
状态。网址是跟随重定向后的最终网址;标头的名称一律小写,同名多值以,连接,Set-Cookie不可见;正文是响应体按严格 UTF-8解码的文字(HEAD与 204、205 响应为空文字);字节数是响应体的字节数。 - 成为假:
原因只有四种——网络错误(连接失败、被重定向到别的来源、被浏览器拒绝等)、超时、正文过大、正文不是有效UTF-8;说明是中文说明。 - 两种对象都带
标记(省略时为空文字)。
函数
发起网页请求 : 字符串 → 整数
校验请求 JSON 后立即返回请求号(正整数,实例内单调递增,不复用),请求在后台进行。结束时投递一个事件:类型 请求,订阅号 = 请求号,名称 为 完成(成为真)或 失败(成为假),详情 为响应 JSON。同时“在途或结果尚未被应用取走”的请求至多 32 个(含阻塞变体的请求),已达上限时抛事故——应用应把并发控制在自己的状态机里,并及时取走结果事件。
取消网页请求 : 整数 → 爻
取消一个请求。请求仍在进行,或它的结果事件还在队列里没被取走时,中止请求、移除该事件并返回阳;请求号未知,或结果事件已经被应用取走时返回阴。取消之后保证不再收到该请求号的事件,因此应用可以把“旧请求的响应不得覆盖新状态”这类竞态用取消或世代号解决。
请求网页文字 : 字符串 → 字符串
阻塞变体:参数同 发起网页请求,挂起当前调用,直到请求结束,返回响应 JSON。等待期间其他事件照常进入队列,但应用在这次调用返回之前不会处理它们,因此只适合启动时的一次性读取或明确希望串行的场景;需要并发或可取消的请求用 发起网页请求。违规调用抛事故,网络类失败归入响应(成为假),不抛事故。阻塞变体不可取消,不产生事件,也占用并发名额。
事件
等待网页事件 返回的事件 JSON 形如
{"类型":"请求","序":42,"订阅号":7,"名称":"完成","详情":{"成":true,"状态":200,…}}
“请求”类型的事件队列独立计数,默认上限 1024;并发上限 32(含结果未取走的请求)保证不会因积压而丢失结果。
限额与失败分类
| 项 | 限额 | | --- | --- | | 并发在途请求(含结果尚未取走者) | 32 | | 请求 JSON | 10 MiB;请求正文 8 MiB;网址 8192 码元;标头 32 项 | | 响应正文 | 默认 8 MiB,可配至 16 MiB | | 超时 | 默认 60 秒,可配 1 毫秒至 10 分钟 |
- 违规调用(请求 JSON 无效、字段未知或越界、网址非同源、并发已满、宿主已关闭)抛豫言事故,消息为中文并指出出错字段。
- 运行时失败(网络错误、超时、正文过大、正文不是有效 UTF-8)是响应的一种,
成为假,不抛事故。 - 取消不产生任何事件。
一致性样例
发起网页请求({"网址":"/api/甲","标记":"a"})返回 1;等待网页事件得类型请求、订阅号 1、名称完成、详情状态为 200、标记为a、正文为服务器返回的文字。- 服务器返回 404 与 JSON 错误体:仍是
完成,状态为 404,正文含错误体。 - 三个请求同时发起,服务器按相反顺序返回:三个事件按到达顺序进入队列,各自订阅号不同。
- 发起后立即
取消网页请求:返回阳,之后队列里没有该请求号的事件。 - 服务器断开连接:
失败,原因为网络错误;响应体含无效 UTF-8 字节:失败,原因为正文不是有效UTF-8。 网址为https://别处.站/x:抛事故(非同源);第 33 个并发请求:抛事故。请求网页文字对/api/甲返回响应 JSON,等待期间到达的点击事件仍在队列里,返回后可取到。
边界
本包不规定:跨来源请求(CORS)、请求与响应的流式读写(服务端事件流见网页事件源包)、二进制正文与文件上传、进度事件、FormData、Service Worker、HTTP 缓存细节、fetch 的 keepalive 与优先级。