WinHttp.WinHttpRequest 添加到内容类型

Posted

技术标签:

【中文标题】WinHttp.WinHttpRequest 添加到内容类型【英文标题】:WinHttp.WinHttpRequest adding to the content-type 【发布时间】:2016-06-09 02:06:51 【问题描述】:

我正在尝试使用 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

有什么想法吗?

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

【问题讨论】:

他们期待什么字符集?您是否尝试在您的 Content-Type 字符串中指定它? 内容类型应该只有 application/json 没有其他内容,如果内容类型有任何超出 application/json 的内容,我会收到错误消息。是的,我尝试指定 Content-Type 字符串。这发生在我设置请求之后。 尝试用分号结束你的字符串。运气好吗? 我试过了,没有运气。我的问题类似于link 嗯.. 看起来不太好.. VBA 是您唯一的选择吗?祝你好运! 【参考方案1】:

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

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

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

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

因此,如果您发布的 XML 文本数据包含 LATIN-1 字母数字 或标点符号代码(每个小于十进制 128),然后你 应该做的是在您的 Content-Type 中指定“ISO-8859-1”字符集 标题:

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

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

问候,

斯蒂芬·苏尔泽

微软公司


除了以二进制数组发送之外,第二个选项是切换到Msxml2.XMLHTTPMsxml2.ServerXMLHTTP。这些都不会破坏 Content-Type 标头。幸运的是,在创建WinHttp.WinHttpRequest 时,微软有意使用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)

【讨论】:

Since VBA doesn't have strongly typed arrays - VBA 具有强类型数组。 VBScript 是另一种语言。 @GSerg 谢谢。我不知道。我已经从我的回答中删除了这句话。 只是更改为 Set objHTTP = CreateObject("Msxml2.XMLHTTP") 对我有用。

以上是关于WinHttp.WinHttpRequest 添加到内容类型的主要内容,如果未能解决你的问题,请参考以下文章

Msxml2.ServerXMLHTTP 和 WinHttp.WinHttpRequest 之间的区别?

WinHTTP.WinHTTPRequest.5.1 在 TLS 1.2 之后不适用于 PayPal 沙箱

asp.net javascript WinHttp.WinHttpRequest

WinHttpRequest 超时

在VBA WinHttpRequest上捕获超时

VBS通过WinHttp对象下载网页图片。