【问题标题】:WinHttpRequest Object returns "â??" instead of "✓" (U+2713) [duplicate]WinHttpRequest 对象返回“â??”而不是“✓”(U + 2713)[重复]
【发布时间】:2021-09-07 07:27:38
【问题描述】:

我正在使用 Excel 2007 (12.0.4518.1014)

我一直在使用 WinHttpRequest 对象在为我托管数据的 Web 服务上执行 API GET 请求。

其他一切工作正常,它从 Web 服务中获取 JSON 格式的数据并将其放入带有 .ResponseText 属性的字符串中。

我遇到的问题是,在该字符串中,所有 Unicode 字符都变成了像 â?? 这样的乱码,而不是 (U+2713)。这意味着当我执行MyRange.Value = .ResponseText 时,单元格值变为â??

如果我将 GET 请求设置为请求 Xml 格式,我会得到 �?? 而不是

我已通过在 Chrome 中重复 GET 请求确认,网络服务正在输出正确的 Unicode 符号,并且 Chrome 能够向我显示 。所以这是 VBA 或 WinHttp 的问题。

Excel 本身能够生成 Unicode 符号,而 VBA 也能够做到这一点ChrW(10003)

如何在 GET 请求期间保留 Unicode 符号?是否可以使用 WinHttp 或者我需要更改方法?

编辑:

这是标准响应期间的标头:

{
  "access-control-allow-headers": "Content-Type",
  "access-control-allow-methods": "GET, POST, PUT, DELETE, OPTIONS",
  "access-control-allow-origin": "*",
  "cache-control": "private",
  "content-encoding": "gzip",
  "content-security-policy": "frame-ancestors 'self', default-src * 'unsafe-inline' 'unsafe-eval' data: blob:;",
  "content-type": "application/json",
  "date": "Wed, 23 Jun 2021 18:08:53 GMT",
  "expect-ct": "max-age=0;",
  "referrer-policy": "strict-origin-when-cross-origin",
  "strict-transport-security": "max-age=31536000; includeSubDomains; preload",
  "vary": "Accept-Encoding",
  "x-content-type-options": "nosniff",
  "x-frame-options": "SAMEORIGIN",
  "x-stackifyid": "V2|80002f92-0000-3100-b63f-84710c7967bb|C61313|CD10436"
}

更新:已解决!

我已经通过@GSerg 的建议和@JoelCoeHoorn 的精彩见解解决了我的问题。自从我的问题结束后,我将在这里写下它是如何解决的。

WinHTTPRequest 被替换为 XMLHTTP 对象。这个对象可以在 VBA 中使用与 WinHTTPRequest 类似的命令,如页面中间的链接所示。但是 XMLHTTP 对象能够毫无问题地返回 Unicode 字符。

要在 VBA 中使用它,您可以使用以下行创建它:

    Dim http As Object
    Set http = CreateObject("Microsoft.XMLHTTP")

然后您就可以使用类似于 WinHttpRequest 对象的.open.setRequestHeader.Send

【问题讨论】:

  • 这看起来有点像 UTF-8 字节顺序标记。
  • @JoelCoehoorn 我可以去哪里学习如何在 VBA 中解码 UTF-8?你有什么建议吗?
  • 不,这会进入请求,而不是响应,并且服务器必须准备好接受该请求(如果您已硬编码 "content-encoding": "gzip",则可能不会)。因此,在您这样做之前,请尝试在 VBA 中使用 XMLHTTPRequest 而不是 WinHttpRequest。
  • @GSerg 谢谢!!!! XMLHTTP 对象完美运行!它能够在同一地址获取并返回一个真正的复选标记而不是乱码。如果您愿意,请将您的笔记和建议作为答案提交,我会将此问题标记为已回答。

标签: excel vba winhttp winhttprequest


【解决方案1】:

我知道与 HTTP 事务相关的五种方式:

响应有一个标头,其中包含使用的特定编码。如果选择的编码不能显示文本中使用的所有字符点,这就是你得到的。

如果响应的文本直接设置并且未映射到标头中指定的编码,这也是您得到的,因此编码表明文本应该与实际不同。

由于历史原因,有些编码依赖于系统,其中编码的上部区域取决于本地安装的语言包/设置。因此,如果标头选择系统特定的编码并且文本设置在系统上,即使两端使用相同的编码,该上部区域的解释与客户端不同,您也可以看到这种效果。

当字节顺序标记被错误使用、忽略或解释为文本时,可能发生这种情况的第四种方式是使用 UTF-8。

最后,(这是最有可能适合您的情况的这些选项)当在一个地方使用了另一个不支持的编码时,可能会发生这种情况。 VBA 早于 unicode 的广泛采用,并且没有良好的 unicode 支持。尤其是旧版本的 VBA,比如您可能会在长期不受支持的 Excel 2007 中遇到这种情况。

这些问题都倾向于只针对 unicode 字符表现出来,而忽略简单的拉丁字符,因为许多编码都以完全相同的方式处理简单的拉丁字符。

【讨论】:

  • 我对 REST 请求和标头仍然非常缺乏经验,我将在我的帖子中添加所有标头及其默认设置的示例,您可以看看是否有什么我可以做的如何使其与 Excel/VBA 兼容?
  • 我这里有 Excel 2003,其中的 VBA 和往常一样完全是 Unicode。 WinHttpRequest 应该将其任何编码解码为 VBA 使用的 UTF-16。
  • 第六个选项,WinHttpRequest has problems with gzip...
  • @GSerg 你应该把它变成这个问题的新答案。从技术上讲,这将是一个愚蠢的问题,但这是提问者很难找到原件的情况之一,因为他们最初不知道涉及 gzip,因此可能需要一个新的答案。
猜你喜欢
  • 2021-09-18
  • 2021-04-28
  • 2021-05-20
  • 2021-08-09
  • 2017-10-01
  • 2012-09-28
  • 1970-01-01
  • 2019-03-17
相关资源
最近更新 更多