You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用VBA MSXML2.XMLHTTP正确编码GIF适配Confluence附件API?

解决Confluence Create Attachment API上传GIF损坏问题

核心问题分析

  • VBA字符串默认是UTF-16编码,而GIF属于二进制文件,包含大量非UTF-16兼容的字节(如0x00、单字节扩展ASCII)
  • 你当前使用的StrConv(fileStream.Read(), vbUnicode)会把二进制字节按系统默认代码页转成UTF-16字符串,这个过程会丢失或篡改原始二进制数据,导致上传后的文件损坏
  • 直接用字符串拼接multipart/form-data请求体,会因VBA字符串的编码特性进一步破坏文件内容

正确解决方案:用ADODB.Stream拼接二进制请求体

全程使用ADODB.Stream处理二进制流,避免将文件数据转成VBA字符串,确保请求体的二进制完整性:

步骤1:编写二进制文件读取函数

直接返回文件的字节数组,不做编码转换:

Function ReadFileBinary(filePath As String) As Byte()
    Dim fileStream As Object
    Set fileStream = CreateObject("ADODB.Stream")
    fileStream.Type = 1 ' 二进制模式
    fileStream.Open
    fileStream.LoadFromFile filePath
    
    ReadFileBinary = fileStream.Read()
    
    fileStream.Close
    Set fileStream = Nothing
End Function

步骤2:构建完整的multipart/form-data二进制流

用ADODB.Stream依次拼接边界、文本字段和二进制文件数据:

Sub UploadGifToConfluence()
    Dim http As Object
    Set http = CreateObject("MSXML2.XMLHTTP.6.0")
    
    Dim boundary As String
    boundary = "------IMabOUnDdfdfAaAAAA" ' 自定义边界,确保不与文件内容冲突
    
    Dim reqStream As Object
    Set reqStream = CreateObject("ADODB.Stream")
    reqStream.Type = 1 ' 二进制模式
    reqStream.Open
    
    ' 写入文件字段的头部文本(转成UTF-8二进制)
    Dim fileHeader As String
    fileHeader = "--" & boundary & vbCrLf & _
                 "Content-Disposition: form-data; name=""file""; filename=""ttmRecordTypeImage19.gif""" & vbCrLf & _
                 "Content-Type: image/gif" & vbCrLf & vbCrLf
    reqStream.Write StrConv(fileHeader, vbFromUnicode)
    
    ' 写入GIF二进制数据
    reqStream.Write ReadFileBinary("C:\你的文件路径\ttmRecordTypeImage19.gif")
    
    ' 写入minorEdit字段(转成UTF-8二进制)
    Dim fieldContent As String
    fieldContent = vbCrLf & "--" & boundary & vbCrLf & _
                   "Content-Disposition: form-data; name=""minorEdit""" & vbCrLf & vbCrLf & _
                   "true" & vbCrLf & _
                   "--" & boundary & "--" & vbCrLf
    reqStream.Write StrConv(fieldContent, vbFromUnicode)
    
    ' 定位到流的起始位置
    reqStream.Position = 0
    
    ' 发送请求
    http.Open "POST", "https://你的Confluence域名/rest/api/content/{contentId}/child/attachment", False
    http.setRequestHeader "Authorization", GetAuth
    http.setRequestHeader "X-Atlassian-Token", "nocheck"
    http.setRequestHeader "Content-Type", "multipart/form-data; boundary=" & boundary
    
    ' 发送二进制流数据
    http.send reqStream.Read()
    
    ' 处理响应结果
    If http.Status = 200 Or http.Status = 201 Then
        Debug.Print "上传成功"
    Else
        Debug.Print "上传失败:" & http.Status & " - " & http.responseText
    End If
    
    reqStream.Close
    Set reqStream = Nothing
    Set http = Nothing
End Sub

关键细节说明

  • 禁止用字符串承载二进制数据:VBA字符串无法正确存储所有二进制字节(如0x00会被当作字符串结束符),必须用Byte数组或ADODB.Stream处理
  • 文本部分转UTF-8:multipart/form-data的文本字段(边界、头部)需要UTF-8编码,通过StrConv(text, vbFromUnicode)将VBA的UTF-16字符串转成UTF-8二进制
  • 流拼接保证完整性:用ADODB.Stream的Write方法依次拼接各部分,避免手动拼接导致的字节丢失
  • 边界唯一性:边界字符串不要包含文件中可能出现的内容,防止Confluence解析请求体出错

排查验证方法

  1. 对比本地文件与Confluence中附件的MD5值:若不一致,说明数据传输过程中被篡改
  2. 用抓包工具查看请求体中的二进制文件数据,确认与原文件是否一致
  3. 检查Confluence返回的附件元数据,验证文件大小、MD5是否匹配本地文件

内容的提问来源于stack exchange,提问作者Simon

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 22:53:11