我也遇到了这个问题。它似乎仅限于WinHttp.WinHttpRequest
COM 接口。有几个不同的选项可以解决这个问题。
经过一番挖掘,我从一位微软员工那里找到了这篇文章。它给出了清晰的解释,并建议发送二进制数组。
如果您使用 WinHttpRequest 对象发布字符串,则无法覆盖它对字符串进行编码以进行传输的方式。WinHttpRequest 对象将始终将 Unicode 字符串转换为 UTF-8。
但是,请注意,仅包含 7 位 LATIN-1/ISO-8859-1 字符的 Unicode 字符串在编码为 UTF-8 时将保持不变;-) 在这种情况下,WinHttpRequest 对象不会附加“Charset=UTF -8" 属性添加到您的 Content-Type 标头。(而且我认为服务器会假设 POST 数据是 ISO-8859-1。)
因此,如果您发布的 XML 文本数据包含 LATIN-1 字母数字或标点字符代码(每个都小于十进制 128),那么您所要做的就是在您的 Content- 中指定“ISO-8859-1”字符集类型标题:
WinHttpReq.SetRequestHeader "Content-Type", "application/xml;Charset=ISO-8859-1"
但是,如果您的 POST 数据包含 8 位字符,则您不能将数据作为字符串提供给 Send 方法。为了避免 UTF-8 转换,您的应用程序必须将字符串转换为字节数组,并提供它。WinHttpRequest 对象不会尝试对字节数组进行任何数据转换。
问候,
斯蒂芬·苏尔泽
微软公司
除了发送二进制数组之外,第二个选项是切换到Msxml2.XMLHTTP
or Msxml2.ServerXMLHTTP
。这些都不会破坏Content-Type
标题。幸运的是,在WinHttp.WinHttpRequest
创建时,Microsoft 有意将其用作Msxml2.XMLHTTP
界面的模板。因此,转换代码相当简单。
此外,Msxml2.ServerXMLHTTP
COM 接口在内部使用 WinHTTP。因此,虽然您无法访问某些独有的功能,但WinHttp.WinHttpRequest
两者都使用相同的后端。
第三种选择是使用ADODB.Stream
. 它允许您使用IStream
,这不是您通常可以通过 VBA 完成的操作。下面的示例代码基于问题“如何在 VbScript 中创建 BinaryArray?”的答案。.
' Create a Binary Stream
Set objStreamBinary = CreateObject("ADODB.Stream")
objStreamBinary.Type = 1
objStreamBinary.Open
' Create a Text Stream
Set objStreamText = CreateObject("ADODB.Stream")
objStreamText.Type = 2
objStreamText.Open
' Copy the POST data to the Text Stream
objStreamText.WriteText strRequest
objStreamText.Position = 2
' Copy the Text Stream Contents to the Binary Stream
objStreamText.CopyTo objStreamBinary
objStreamText.Close
' Read the contents of the Binary Stream
' and send it to the WinHttpRequest object
web_Http.Send objStreamBinary.Read(-1)