网络和编码 · 5 分钟阅读
URL编码:何时逃跑,何时破坏东西
URL 由对解析器有意义的字符和简单数据的字符组合而成,而百分比编码就是将两者分开的方式。 URL编码器将后者转换为`%XX`转义,因此包含`&`、`?`或空格的值在行程中保留下来。大多数“4”错误根本不是编码失败——而是编码了错误的部分,或者编码了两次。
已更新
必须编码什么
一小组字符始终是安全的 - 字母、数字、`-`、`_`、`.` 和 `~`。其他一切要么被保留,要么应该被转义。保留字符是有趣的字符,因为它们在 URL 中是合法的,但仅在特定位置:`?` 开始查询,`&` 分隔参数,`=` 分配值,`#` 启动片段,`/` 分隔路径段。将其中一个放入未编码的值中,您就默默地重写了 URL 的结构。
加或%20
太空就是一个典型的例子。路径中,空格必须为`%20`; a `+` 有一个字面上的加号。在表单解析器读取的`application/x-www-form-urlencoded`主体和查询字符串中,`+`被理解为空格。这种差异就是为什么一个值可以编码为在一种上下文中工作而在另一种上下文中中断的东西,以及为什么解码器提供这两种解释。
对组件而不是整个 URL 进行编码。通过组件编码器运行完整的 URL 会转义它自己的 `://` 和 `?`,从而生成一个无法解析的链接。
JavaScript 的区别吸引了所有人
encodeURI('https://x.com/a b?q=1') // keeps :// ? = — for a whole URL
encodeURIComponent('a b?q=1') // escapes ? and = — for one value
`encodeURI` 保留URL 结构,用于完整地址; `encodeURIComponent` 转义了所有重要的内容,并且适用于单个参数值。使用错误的值会产生损坏的 URL 或未转义的值,并且症状相反:出现 404 错误的链接,或丢失一半参数的查询字符串。
双重编码和签名 URL
对已编码的值进行编码会将 `%20` 转换为 `%2520`,然后服务器将其解码一次,并将文本 `%20` 传递给您的应用程序,其中原本应该有一个空格。这出现在分层系统中——代理重新编码目标,客户端转义它收到的已经转义的 URL。对于签名 URL 最重要的是:签名是根据精确的编码字符串计算的,因此更改一个字符的转义会使链接无效,即使它仍然解析为相同的资源。
解码调试
当链接出现故障时,对其进行解码是查看服务器实际请求内容的最快方法,而答案通常是泄漏到结构中的值。在浏览器中工作意味着您可以粘贴包含令牌、签名参数或客户标识符的 URL,而无需将其发送到任何地方,这正是您不应粘贴到记录请求的服务中的 URL 类型。
URL 编码器/解码器 — 常见问题
空格应该是 %20 还是加号?
使用`%20`在您自己构建的路径和任何 URL 中;两者在查询字符串中都是有效的,其中表单解析器通常读取`+`作为一个空间。解码需要知道哪个约定产生了字符串。
为什么我的 URL 编码两次会破坏它?
每一遍都会转义转义字符:空格变为`%20`,然后变为`%2520`。到达后,服务器解码一次,您的应用程序会收到原义 `%20` 文本。在原始值成为URL的一部分时编码一次。
encodeURI 和encodeURIComponent 之间有什么区别?
`encodeURI` 完整保留`://`、`?`、`&` 和`=` 等结构字符,因此它适合整个地址。 `encodeURIComponent` 也会转义这些,因此它适合单个参数值。将它们混合在一起是大多数损坏的生成链接的原因。
这篇文章中提到的工具
更多文章可供阅读
5 分钟阅读
Base64 解码和编码:用于传输,而不是安全
Base64 在浏览器中解码和编码 — 4/3 大小规则、填充、base64url 变体以及使解码文本看起来像垃圾的 Unicode 错误。
5 分钟阅读
cURL to fetch:将请求从终端移动到浏览器
用于获取 JavaScript 转换的 cURL:正确映射的标头、正文、身份验证和方法,以及决定请求是否有效的 CORS 现实。
6 分钟阅读
JWT 解码器:令牌内包含什么,不包含什么
使用 JWT 解码器检查令牌的标头、有效负载和过期时间,并了解解码未验证的原因,大多数 401 背后都有声明检查。