使用 VBA 和 MS XMLHTTP 将文件上传到 Azure Blob 存储

Uploading a file to Azure Blob Storage using VBA and MS XMLHTTP

我一直在尝试在 Microsoft Access 中使用 VBA 将文件上传到 Azure 存储,但到目前为止没有成功。

我仔细搜索了一下,找到了一些看起来很有前途但无法正常工作的代码。似乎许多其他人一直在寻找类似的解决方案或帮助 VBA 使用 Azure。

这是代码;

Private Function pvPostFile(sUrl As String, sFileName As String, Optional ByVal bAsync As Boolean) As String
Const STR_BOUNDARY  As String = "3fbd04f5-b1ed-4060-99b9-fca7ff59c113"
Dim nFile           As Integer
Dim baBuffer()      As Byte
Dim sPostData       As String

'--- read file
nFile = FreeFile
Open sFileName For Binary Access Read As nFile
If LOF(nFile) > 0 Then
    ReDim baBuffer(0 To LOF(nFile) - 1) As Byte
    Get nFile, , baBuffer
    sPostData = StrConv(baBuffer, vbUnicode)
End If
Close nFile
'--- prepare body
sPostData = "--" & STR_BOUNDARY & vbCrLf & _
    "Content-Disposition: form-data; name=""uploadfile""; filename=""" & Mid$(sFileName, InStrRev(sFileName, "\") + 1) & """" & vbCrLf & _
    "Content-Type: application/octet-stream" & vbCrLf & vbCrLf & _
    sPostData & vbCrLf & _
    "--" & STR_BOUNDARY & "--"
'--- post
With CreateObject("Microsoft.XMLHTTP")
    .Open "POST", sUrl, bAsync
    .SetRequestHeader "Content-Type", "multipart/form-data; boundary=" & STR_BOUNDARY
    .Send pvToByteArray(sPostData)
    If Not bAsync Then
        pvPostFile = .ResponseText
    End If
End With
End Sub

Private Function pvToByteArray(sText As String) As Byte()
    pvToByteArray = StrConv(sText, vbFromUnicode)
End Function

(感谢 - https://wqweto.wordpress.com/2011/07/12/vb6-using-wininet-to-post-binary-file/

当我使用我的 Azure 存储 URL 形式尝试此代码时

https://XXXXX.blob.core.windows.net/ 

和文件名 (C:\Temp\Test.txt) 我收到以下错误;

<?xml version="1.0" encoding="utf-8"?><Error><Code>UnsupportedHttpVerb</Code><Message>The resource doesn't support specified Http Verb.

我怀疑 header 或 post 数据有问题,而不是 VBA,这不是我的领域。

非常感谢任何帮助。

Azure 存储服务使用私钥身份验证。由于 VBA 在最终用户的机器上运行,您将面临与该密钥泄露相关的一系列风险。我建议重新考虑直接从 VBA 到 Azure 存储并利用您自己的 WebAPI 处理将数据存储到 Blob 的整个前提。

这会带来双重好处:

1) 更容易与 VBA 和

集成

2) 在未部署到最终用户计算机的解决方案组件后面保护您的 Azure 存储私钥。

我在搜索有关将图像上传到 Azure Blob 存储的相同答案时遇到了这个 post。我花了 2 天时间才得到答案。上面的代码 posted 确实帮助我部分解决了问题。

我想在这里 post 我的解决方案,以防其他人正在寻找相同的答案。

在使用下面的代码之前,您需要从 Azure 门户(管理面板)获取共享访问签名 (SAS)。您应该能够 google 回答这个问题。

Public Sub UploadAfIle(sUrl As String, sFileName As String)
    Dim adoStream As Object
    Set adoStream = CreateObject("ADODB.Stream")
    adoStream.Mode = 3          ' read write
    adoStream.Type = 1          ' adTypeBinary
    adoStream.Open
    adoStream.LoadFromFile (sFileName)
    With CreateObject("Microsoft.XMLHTTP")
        adoStream.Position = 0
        .Open "PUT", sUrl, False
        .setRequestHeader "Content-Length", "0" 'this is not a must
        .setRequestHeader "x-ms-blob-type", "BlockBlob"
        .Send adoStream.Read(adoStream.Size)
    End With
    Set adoStream = Nothing
End Sub

sURL 是一个 URL 的样子(我在中国所以 Host 不同):https://myaccount.blob.core.chinacloudapi.cn/products/newimagename.jpg?sv=2016-05- 31&ss=bfpq&srt=dco&sp=rydlscup&se=2017-07-30T18:40:26Z&st=2017-07-28T10:40:26Z&spr=https&sig=mJgDyECayITp0ivVrD4Oug%2Bz%2chN7Wpo2nNtcn0pYRCU=%4d[=123]][=123]

粗体是您从 Azure 生成的 SAS 令牌。

值得注意的是SiliconXu的回答中sUrl的格式由3部分组成,一开始没看懂所以头疼了!!

1) Azure blob 容器 URL(来自存储资源管理器中的属性) 2)文件名(这是我漏掉的部分) 3) 共享访问签名

所以是这样建造的

sURL = destination_folder & "/" & local_file_name & "?" & conn_SAS

我不具备直接在该答案下方发表评论的声誉

很棒的代码,一旦我确定了 sURL 的格式,它就像梦一样工作