WinHttp.WinHttpRequest添加到内容类型

时间:2016-02-26 01:42:24

标签: vba ms-access winhttp winhttprequest

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

我像这样设置内容类型

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

但是当我在Wireshark中查看请求时,content-type就是这样的

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

有什么想法吗?

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

1 个答案:

答案 0 :(得分:2)

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

经过一番挖掘后,我发现了一名来自Microsoft员工的this post。它给出了明确的解释,并建议发送二进制数组。

  

如果使用WinHttpRequest对象发布字符串,则不能   覆盖它如何编码字符串以进行传输。 WinHttpRequest   object始终将Unicode字符串转换为UTF-8。

     

但是,请注意只包含7位的Unicode字符串   编码为UTF-8时,LATIN-1 / ISO-8859-1字符将保持不变   ;-)在这种情况下,WinHttpRequest对象不会附加   "字符集= UTF-8"属性到您的Content-Type标头。 (而且我会想   服务器会认为POST数据是ISO-8859-1。)

     

因此,如果您正在POST的XML文本数据包含LATIN-1字母数字   或标点字符代码(每个小于十进制128),然后你所有   应该做的是指定" ISO-8859-1"内容类型中的字符集   头:

     

WinHttpReq.SetRequestHeader "Content-Type", "application/xml;Charset=ISO-8859-1"

     

但是,如果您的POST数据包含8位字符,则无法提供   数据作为Send方法的字符串。为了避免使用UTF-8   转换时,您的应用程序必须将字符串转换为字节数组,并且   提供相反的。 WinHttpRequest对象不会尝试任何数据   转换为字节数组。

     

此致

     

Stephen Sulzer

     

Microsoft Corporation

除了发送二进制数组外,第二个选项是切换到Msxml2.XMLHTTPMsxml2.ServerXMLHTTP。这两个都没有Content-Type标题。幸运的是,在创建WinHttp.WinHttpRequest时,Microsoft故意使用Msxml2.XMLHTTP作为接口的模板。因此,转换代码非常简单。

此外,Msxml2.ServerXMLHTTP COM接口uses WinHTTP internally。因此,当您无法访问WinHttp.WinHttpRequest专有的某些功能时,两者都使用相同的后端。

第三种选择是使用ADODB.Stream。它允许您使用IStream,这是您通常可以从VBA执行的操作。以下示例代码基于问题"How to create BinaryArray in VbScript?"的答案。

' 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)