网址查询之约 0.1.0
此包具三术,惟作文字之运算,依 WHATWG application/x-www-form-urlencoded 之规,成查询串、析查询串,并改网址之一查询参。三术无权限之求、无外效;今惟云工有适配(借宿主之 URLSearchParams 与 URL),他宿主若承之,须得同果。
编码查询串 项列 受有序(名,值)之列,返表单编码之查询串(即 new URLSearchParams(项列).toString()):空格作 +;除字母、数及 *-._ 外皆依 UTF-8 作百分号编码,故 !'()~ 亦被编码;同名之项守其原序;空列得空文;名与值可含任意 UTF-8 及控字符。限额:至多一零二四项,诸名与值之总字节不逾 1 MiB,逾则违约(「查询项超过 1024 项」「查询项总长度超过 1 MiB」)。
解析表单键值 文 依 WHATWG application/x-www-form-urlencoded 之规而析:以 & 分项,空项不理,首个 = 之前为名,其后为值,+ 视为空格,百分号解之,坏 UTF-8 之序以 U+FFFD 代之;所入之文首字若为 ?,先去此一字(同 URLSearchParams 构造器,故可径授含首问号之原查询串)。返守原序之 [["名","值"],…] JSON 数组文,同名之项各占其一,空入得 [];所返之文乃宿主所书之紧凑 JSON,客当以 JSON 析之,不恃空白与转义之细节。所入不逾 1 MiB,逾则违约(「表单文字超过 1 MiB」)。
设置网址查询参数 网址 键 值 依 URL 与 searchParams.set 之义设一查询参:同名之旧项尽易为一项,居首个同名项之处,余参皆留,并依表单之规重书全查询串(故余参之百分号写法或被规整);片段原样存之。
- 绝对之址:必为
http:或https:(他方案如javascript:、data:、ftp:则败,「绝对网址不是 HTTP(S)」),返完整之href。 - 相对之址:以内部固定基址
https://yuyan-lang.org析之,惟返pathname + search + hash;析后之源若非此基址(如//evil.example/x、\\evil.example)则败(「相对网址不得改变来源」),不可析则败(「网址无效」)。 - 限额:网址、键、值各不逾 64 KiB(「网址、键或值超过 64 KiB」)。键与值可含任意 UTF-8 及控字符,宿主自为编码,不伤参数。
败之类
违约(可捕之事故):项数或总长逾限、所入逾限、网址无效、方案非 HTTP(S)、相对之址易源。此包无业务之情分支:果恒为文。
一致之例
| 调用 | 必见 |
| --- | --- |
| 编码查询串 授 [("a b","1+2"),("a b","!'()~-._")] | `a+b=1%2B2&a+b=%21%27%28%29%7E-._` |
| 编码查询串 授 [("名","\u0001\n")] | %E5%90%8D=%01%0A |
| 解析表单键值 授 a=1&b=x+y%20z&a=%E4%BD%A0&c&d=%ff&=e | [["a","1"],["b","x y z"],["a","你"],["c",""],["d","\ufffd"],["","e"]](JSON 中之 U+FFFD 可以字面或转义书之) |
| 解析表单键值 授 ?a=1 | [["a","1"]] |
| 设置网址查询参数 授 /p?a=1&b=2&a=3#h,键 a,值 新 值 | /p?a=%E6%96%B0+%E5%80%BC&b=2#h |
| 设置网址查询参数 授 https://h.example/p?a=1,键 b,值 2 | https://h.example/p?a=1&b=2 |
| 设置网址查询参数 授 //evil.example/x 或 javascript:alert(1) | 违约 |
所不为
不发网请,不析不验主机名,不作路径规整以外之网址改写,不支持数组式(a[]=)或嵌套之查询约定,不供多值之删,亦不排序诸参。
补:表单项数之限与首 BOM(独立审后修订)
解析表单键值至多一千二十四项(以URLSearchParams.size计),逾者抛可捕之「表单项数超过 1024」,免一 MiB 之表单产五十余万项而拖累癸象之解析。- 文授宿主 TextDecoder 用
ignoreBOM: true:文首之 U+FEFF 存之。