开发者工具·URL编码器和解码器
encodeURI 与encodeURIComponent:各自保留哪些字符
· 工作原理
url 编码 JavaScript 开发人员工作流程
这两个 JavaScript 函数正好相差 11 个字符,选择错误的函数要么会破坏 URL,要么无法转义值。这篇文章详细说明了这些集合并给出了您可以记住的规则。
搜索返回了所有内容,因为“R&D”中的 & 分割了查询——来自错误函数的具体错误
如果代码手动构造 ?q=R&D,则搜索 R&D 可能会意外返回 R 结果。 & 符号是查询参数之间的分隔符;除非您对该值进行编码,否则它不会保留为 q 的一部分。为该小块选择encodeURI 是错误,而不是服务器错误。应用程序代码中最安全的选项通常是 URLSearchParams,但是了解两个 JavaScript 原语可以使现有代码更容易调试。
这两个函数共享的内容——它们从未触及的未保留集以及它们都应用的 UTF-8 百分比编码
两种方法都保留 ASCII 字母、数字和未保留的标点符号 - _ 。 ! ~ * ' ( ) 在 JavaScript 的编码规则下保持不变。他们在写入百分比三元组之前将非 ASCII 字符转换为 UTF-8 bytes:é 变为 %C3%A9,而不是单个拉丁语-1 byte。他们还将空格编码为 %20。百分比编码是为了保留 URI 的结构;它不是 HTML 转义、输入验证或针对接收页面上的恶意脚本的保护。
仅encodeURI 保留这十一个字符 — ; , / ? : @ & = + $ # 以及为什么每个在 URL 中都具有结构含义
encodeURI 另外保留了encodeURIComponent 编码的十一个结构字符: , / ? :@&=+$#。对于完整的地址,单独保留斜杠和问号可以保留其路径和查询语法。对于查询值,让 & 或 = 通过将更改参数列表,而未转义的 # 可以启动片段。这些函数的不同之处在于,一个函数用于整个地址,另一个函数用于该地址内的组件。
一条规则:值获取encodeURIComponent,完整的URL获取encodeURI——以及为什么“完整的URL”比听起来更罕见
值几乎总是得到encodeURIComponent;对于encodeURI来说,完整的、已经结构化的地址是不太常见的情况。对于以编程方式构建的 URL,请使用 URL API 来处理路径和搜索参数,而不是连接编码片段和原始片段的混合。不要使用encodeURIComponent 对整个URL 进行编码,然后期望斜杠和冒号继续充当分隔符。相反,不要通过encodeURI 提供用户的查询项并使其与符号保持活动状态。
工作示例:两个函数使用相同的字符串 — 包含空格、&、/ 和重音符号的值的输出表
以R&D/café作为一个查询值。 encodeURIComponent 返回 R%26D%20%2F%20caf%C3%A9,保护 & 符号和斜杠。 encodeURI 返回 R&D%20/%20caf%C3%A9,保留结构标点符号;一个简单的 ?q= 前缀现在会创建一个意外的分隔符。两者都对空格和重音进行编码,因此仅使用“hello world”的测试会错过重要的区别。比较 ToolAcre 中生成的字符串,然后将它们粘贴到 URL 解析器中并检查出现了多少个查询参数。
常见错误 — 使用encodeURIComponent 对完整 URL 进行编码,并使用错误的对应项进行解码
将完整 URL 编码为一个组件会生成 %3A%2F%2F,而消费者期望的是 ://。在验证之前解码整个地址可以重新引入具有新含义的保留分隔符。还要避免对已经包含 %26 的值进行双重编码:百分号本身可以变成 %25,因此第二个解码层可能会再次改变含义。将组件的encodeURIComponent 与decodeURIComponent 配对,并将格式错误的百分比转义视为输入错误。
这不包括什么 - 使用 + 进行表单编码,以及使用 URLSearchParams 构建 URL
HTML 表单查询编码在 application/x-www-form-urlencoded 中使用加号表示空格,这与这两个函数的 %20 输出不同。 URLSearchParams 为您处理这些表单规则。本文不涉及路径规范化、Unicode 主机名转换或确定解码后的 URL 是否可以安全请求; URL 编码是表示步骤,而不是授权策略。
要点:对部分而不是整体进行编码 — URL 编码器和解码器如何显示两种模式,以便您可以看到自己输入的差异
令人难忘的边界是部分与整体:参数值是一部分,因此请使用encodeURIComponent 或URLSearchParams。 URL 编码器和解码器显示同一字符串的两个浏览器功能,并将实验保持在本地。在确定两个编码器可以互换之前,测试包含 &、=、#、斜线和重音符号的输入。