首页 > 解决方案 > 解释 HTTP 响应正文的内容。面对一些意想不到的前缀数据

问题描述

我正在尝试从 VBA 代码中下载 PDF 文件(提供给我的 URL)。我正在创建一个 WinHTTPReq 对象 (MSXML6.XMLHTTP60)。我将内容类型设置为 application/pdf

一切正常但是由于某种原因我写的文件(我正在将 responsebody 结果写入文件)包含一个 12 字节的标题(中间 4 是 PDF 的实际文件长度)

如果我单击 URL 并从浏览器下载 PDF,则这些字节不存在。

我尝试使用内容类型有点无济于事。我用谷歌搜索以更好地理解这个 12 字节前缀,但没有结果。

Private Function DownloadFileFromURL(sURL As String, sOutputFileSpec) As Boolean
  Dim WinHttpReq As New MSXML2.XMLHTTP60
  Dim iFileHandle As Integer
  Dim s As String

  WinHttpReq.Open "GET", sURL, False
  WinHttpReq.setRequestHeader "Content-Type", "application/pdf"
  WinHttpReq.send

  If WinHttpReq.Status = 200 Then
    iFileHandle = FreeFile()
    Open sOutputFileSpec For Binary Access Write As iFileHandle
    Put #iFileHandle, 1, WinHttpReq.responseBody

    Close iFileHandle
    DownloadFileFromURL = True
  Else
    DownloadFileFromURL = False
  End If
End Function
 od -x Test.pdf 
0000000      2011    0001    f39a    0016    0000    0000    5025    4644
0000020      312d    342e    250d    e3e2    d3cf    0a0d    3437    3020
0000040      6f20    6a62    3c0a    2f3c    694c    656e    7261    7a69

我不知道 2011 0001 f39a 0016 0000 0000 的原因...(顺便说一句 0x0016f39a 是 PDF 文件的长度(没有 12 个字节)。在此之后文件真正开始 5025 4644 (= %PDF)

标签: vbahttppdfmsxml

解决方案


12 字节前缀来自 VBA 的 Put 命令。声明的类型ResponseBodyis Variant,并且 Put 具有在写出 Variant 内容之前注释变体类型的逻辑。

您需要在写出之前将内容复制到字节数组中。它会去:

If WinHttpReq.Status = 200 Then
    Dim Body() As Byte
    ReDim Body(UBound(WinHttpReq.responseBody)) As Byte
    Body = WinHttpReq.responseBody

    iFileHandle = FreeFile()
    Open sOutputFileSpec For Binary Access Write As iFileHandle
    Put #iFileHandle, 1, Body

    Close iFileHandle


推荐阅读