10

我正在尝试使用 vba WinHttp.WinHttpRequest 向 kigo 的 api 发出请求,我能够发送请求,但是 WinHttpRequest 在发送请求时更改了添加 Charset=UTF-8 的内容类型,并且该 kigo 的 api 返回 415错误。

我这样设置内容类型

web_Http.SetRequestHeader "Content-Type", "application/json"

但是当我在 Wireshark 中查看请求时,内容类型是这样的

Content-Type: application/json; Charset=UTF-8

有任何想法吗?

我发现了这个,这与我的问题相似,但我不明白解决方案。

4

1 回答 1

6

我也遇到了这个问题。它似乎仅限于WinHttp.WinHttpRequestCOM 接口。有几个不同的选项可以解决这个问题。

经过一番挖掘,我从一位微软员工那里找到了这篇文章。它给出了清晰的解释,并建议发送二进制数组。

如果您使用 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.XMLHTTPor Msxml2.ServerXMLHTTP。这些都不会破坏Content-Type标题。幸运的是,在WinHttp.WinHttpRequest创建时,Microsoft 有意将其用作Msxml2.XMLHTTP界面的模板。因此,转换代码相当简单。

此外,Msxml2.ServerXMLHTTPCOM 接口在内部使用 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)
于 2016-08-19T06:08:42.947 回答