使用 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 的格式,它就像梦一样工作
我一直在尝试在 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 的格式,它就像梦一样工作