【问题标题】:What to use instead of dontReplace for constructing a data URI?用什么代替 dontReplace 来构造数据 URI?
【发布时间】:2017-09-18 15:39:52
【问题描述】:

过时的 Uri(string, bool) 构造函数用于从已经转义的字符串构造 URI(如果出现无效字符串,过时可能不会破坏程序)。但是,我发现自己需要通过 URI 传递文字字节,我想不出更好的编码方式。

我正在构建一个data: URI,这是一种传递整个资源而不是其标识符的标准化方法。虽然我知道它有一个 ;base64 说明符来将传递的数据标记为以 base64 编码,但在某些情况下,如果没有 base64,URI 会更短,例如二进制数据较少时。因为我不想担心编码,我只想将字节与 URI 一起作为 URI 编码字符串传递,使用 HttpUtility.UrlEncode(byte[])

由于我实际上别无选择,只能让 .NET 为我编码字符串,而不必使用过时的构造函数,并且没有 Uri(byte[]) 构造函数(我认为应该有),什么是构建 URI 的选项?

我考虑过使用Encoding.GetEncoding(1252) 从字节创建一个字符串并使用它,因为 cp1252 可以解码任何字符,但似乎内部 Uri 编码方法使用 UTF-8 编码字符,所以我发现根本无法使用文本编码。

我有哪些选择?如果没有其他办法,是否可以继续使用过时的构造函数?

【问题讨论】:

    标签: c# .net encoding uri data-uri


    【解决方案1】:

    在某些情况下,如果没有 base64,URI 会更短,例如二进制数据较少时

    每次没有 base64 的 URI 都会更短,因为 base64 从八位字节中刻意限制的字符库中生成文本。

    当数据为文本时,不能使用时基64。否则结果将是乱码。

    因为cp1252可以解码任何字符

    不,它只能编码 251 个字符,不像 UTF-8 可以编码 UCS 中的每个字符。 UTF-8 无法解码每个字节序列,而一些不正确的 CP-1252 实现用某些东西填补了 CP-1252 中的空白(例如 0x81),但即使你可以依赖它(你不能),这也是不明智的因为您正在构建一个字符串,所以编码的问题并不重要,除了任何 % 转义字符,并且它们将始终根据它们在 UTF-8 中的编码进行转义。 (很久以前,URL [术语 URI 还不存在] 可以根据其他编码进行转义,但这不起作用,因为无法知道使用了什么编码,因此自 1998 年以来标准强制要求使用 UTF-8)。

    是否可以继续使用过时的构造函数

    不,它会产生错误的结果。

    URI 建立在文本之上。如果您的数据是文本的,那么只需通过Uri.EscapeDataString() 使用普通 URI 规则对其进行编码。如果您的数据不是文本,则使用 base-64 将其编码为文本,然后从那里开始。不要试图在 URI 中放入一些在 URI 中没有意义的东西。

    【讨论】:

    • 数据 URI 是在 1998 年 RFC 中定义的,根据规范,可以指定一个字符集来正确解释数据。因此,data:text/plain;charset=windows-1250,%A9 显示 © 符号,但 data:text/plain;charset=utf-8,%A9 不显示。数据是根据类型和字符集进行解释的,而不是普遍使用 UTF-8。数据可能不完全是文本的,主要是文本,中间有一些二进制数据,这仍然会使 base64 效率低下。
    • 是的,事实上它与使 UTF-8 成为 URI 中转义工作方式的基础的 RFC 同日发布。
    【解决方案2】:

    好吧,标准的 Uri 构造函数接受预编码的 URI,并且不会替换有效的 % 字符,因此实际上不需要使用 dontReplace 参数从包含编码部分的有效 URI 字符串构造 Uri 时。它们不会被重新编码。

    【讨论】:

      猜你喜欢
      • 2015-01-24
      • 2020-01-04
      • 2021-12-30
      • 2023-03-30
      • 2019-11-28
      • 1970-01-01
      • 2022-08-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多