数据URI中的字符集

11
多年来,阅读不断演变的规范,我一直认为RFC 3986最终确定了UTF-8编码用于转义八进制序列。也就是说,如果我的URI包含%XX%YY%ZZ这样的序列(对于任何方案特定部分的URI),我可以将这个解码后的八进制序列解释为UTF-8,以查找预期的解码信息。实际上,我可以调用JavaScript中的decodeURIComponent()函数,它会自动进行解码。

然后我阅读了 data: URI 的规范RFC 2397,其中包括一个 charset 参数,它(自然地)指示编码数据的字符集。但是这是怎么工作的呢?如果我的 data: URI 中有一个两个八位组编码的序列 %XX%YY,那么 charset=iso-8859-1 是否表示这两个解码后的八位组不应该被解释为 UTF-8 序列,而应该被解释为两个单独的拉丁字符(因为 ISO-8859-1 中的每个字节都代表一个字符)?RFC 2397 似乎表明了这一点,因为它给出了一个“希腊字符”示例:

data:text/plain;charset=iso-8859-7,%be%fg%be

但这意味着 JavaScript 中的 decodeURIComponent()(假设为 UTF-8 编码八位字节)不能用于从数据 URI 中提取字符串,对吗?这是否意味着如果字符集不是 UTF-8,我必须创建自己的解码程序来处理数据 URI?
此外,这是否意味着 RFC 2397 现在与 RFC 3986 冲突,后者似乎指定了 UTF-8?还是 RFC 3986 只涉及“新的 URI 方案”,这意味着 data: URI 方案被纳入其中,并拥有其自己的技术来指定编码的八位字节的含义?
我目前最好的猜测是 data: 有其自己的规则,如果它指示了一个字符集而不是 UTF-8,我将不得不在 JavaScript 中使用其他方法代替 decodeURIComponent()。如果您有任何替代方法的建议,也欢迎分享。
1个回答

7
请记住,data: URI方案描述的资源可以被视为一个文件,由不透明的字节流组成,就像http: URI(相同的字节流,但存储在HTTP服务器上)或者ftp: URI(相同的字节流,但存储在FTP服务器上)或者file: URI(相同的字节流,但存储在本地文件系统上)。只有附加到文件的元数据才赋予了字节流意义。
RFC 2397清楚地规定了如何将这个字节流嵌入到URI本身中(与其他URI方案相反,其中URI提供获取字节流的指令,而不是它包含的内容)。它可能是base64编码,也可能是RFC中给出的百分号编码方法。如果字节流包含许多非ASCII字节,则Base64会更紧凑。 data: URI还描述了它自己的Content-Type,这给出了字节流的预期解释。在这种情况下,由于您使用了text/plain;charset=iso-8859-7,因此字节必须正确地编码为ISO-8859-7文本。字节绝对不会被认为是UTF-8或任何其他字符编码。它将使用您指定的字符编码进行无歧义的解码。

但是假设您将其传输到网页上,网页应该如何知道 text/plain;charset=iso-8859-7,opaque 中的不透明部分在哪里结束?因此,在使用 iso-8859-7 解码之前,应首先使用 HTTP 标头声明的 UTF-8 进行解码。 - Pacerier
UTF-8解码将在URL处理中进行。数据可能会使用UTF-8对数据进行重新编码,以便在非base64模式下获得字节流,然后像不透明的字节流一样处理它。因此,如果您的数据具有无法用UTF-8表示的位序列,则您唯一的选择是将数据编码为base64,因为URL解析器(可能)允许替换或出错于其输入中的无效UTF-8序列。 - binki

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接