我是新工作的HTTP协议,并且已经有一段时间没有使用过VBS了。 我遇到的问题是将参数和上传文件发送到Web服务。 我只是不明白一些代码是什么。以下是代码的一部分。
With CreateObject("MSXML2.ServerXMLHTTP")
.setOption 2, 13056 'http://msdn.microsoft.com/en-
us/library/ms763811(v=VS.85).aspx
.SetTimeouts 0, 60000, 300000, 300000
.Open "POST",
"https://192.168.100.100/api/import_file_here.json", False
.SetRequestHeader "Content-type", "multipart/form-data; boundary=" &
strBoundary 'THIS SEND THE FILE
.SetRequestHeader "Content-Type", "application/x-www-form-urlencoded" '
THIS SEND THE PARAMETER.
.Send bytPD ' sends param
.Send bytPayLoad '''SEND FILE
我知道我不能用。发两次。我相信我需要在下面的代码块中进行更改。
With CreateObject("ADODB.Stream")
.Mode = 3
.Charset = "Windows-1252"
.Open
.Type = 2
.WriteText "--" & strBoundary & vbCrLf
'.WriteText "Content-Disposition: form-data; name=""file""; filename=""" &
strFile & """" & vbCrLf
.WriteText "Content-Disposition: form-data; name=""file"";
publication=""moveit_test_pub"""
'.WriteText "Content-Type: """ & strContentType & """" & vbCrLf & vbCrLf
.Position = 0
.Type = 1
.Write bytData
.Position = 0
.Type = 2
.Position = .Size
.WriteText vbCrLf & "--" & strBoundary & "--"
.Position = 0
.Type = 1
bytPayLoad = .Read
bytPD = "publication=moveit_test_pub"
bytPD =“publication = moveit_test_pub”是我需要的参数以及文件上传。我只是不确定如何将它添加到上面的块中。如果那是我应该改变的地方。我在下面发布了整个代码以供参考。 谢谢你的帮助!
strFilePath = "C:\SCAudience_TEST5.txt"
UploadFile strFilePath, strUplStatus, strUplResponse
MsgBox strUplStatus & vbCrLf & strUplResponse
Sub UploadFile(strPath, strStatus, strResponse)
Dim strFile, strExt, strContentType, strBoundary, bytPD, bytData,
bytPayLoad
On Error Resume Next
With CreateObject("Scripting.FileSystemObject")
If .FileExists(strPath) Then
strFile = .GetFileName(strPath)
strExt = .GetExtensionName(strPath)
Else
strStatus = "File not found"
Exit Sub
End IF
End With
With CreateObject("Scripting.Dictionary")
.Add "txt", "text/plain"
.Add "html", "text/html"
.Add "php", "application/x-php"
.Add "js", "application/x-javascript"
.Add "vbs", "application/x-vbs"
.Add "bat", "application/x-bat"
.Add "jpeg", "image/jpeg"
.Add "jpg", "image/jpeg"
.Add "png", "image/png"
.Add "exe", "application/exe"
.Add "doc", "application/msword"
.Add "docx", "application/vnd.openxmlformats-
officedocument.wordprocessingml.document"
.Add "xls", "application/vnd.ms-excel"
.Add "xlsx", "application/vnd.openxmlformats-
officedocument.spreadsheetml.sheet"
strContentType = .Item(LCase(strExt))
End With
If strContentType = "" Then
strStatus = "Invalid file type"
Exit Sub
End If
With CreateObject("ADODB.Stream")
.Type = 1
.Mode = 3
.Open
.LoadFromFile strPath
If Err.Number <> 0 Then
strStatus = Err.Description & " (" & Err.Number & ")"
Exit Sub
End If
bytData = .Read
bytPD = "publication=moveit_test_pub"
End With
strBoundary = String(6, "-") & Replace(Mid(CreateObject("Scriptlet.TypeLib").Guid, 2, 36), "-", "")
With CreateObject("ADODB.Stream")
.Mode = 3
.Charset = "Windows-1252"
.Open
.Type = 2
.WriteText "--" & strBoundary & vbCrLf
' .WriteText "Content-Disposition: form-data; name=""file""; filename=""" & strFile & """" & vbCrLf
.WriteText "Content-Disposition: form-data; name=""file""; publication=""moveit_test_pub"""
'.WriteText "Content-Type: """ & strContentType & """" & vbCrLf & vbCrLf
.Position = 0
.Type = 1
.Write bytData
.Position = 0
.Type = 2
.Position = .Size
'' .WriteText vbCrLf & "--" & strBoundary & "--"
.Position = 0
.Type = 1
bytPayLoad = .Read
bytPD = "publication=moveit_test_pub"
End With
With CreateObject("MSXML2.ServerXMLHTTP")
.setOption 2, 13056 'http://msdn.microsoft.com/en-us/library/ms763811(v=VS.85).aspx
.SetTimeouts 0, 60000, 300000, 300000
.Open "POST", "https://192.168.100.100/api/import_file_here.json", False
.SetRequestHeader "Content-type", "multipart/form-data; boundary=" & strBoundary 'THIS SEND THE FILE IF BOTH SELECTED SEND PARM AND TEXT OF FILE
.SetRequestHeader "Content-Type", "application/x-www-form-urlencoded" ' THIS SEND THE PARAMETER.
''' .Send bytPD ' sends param
' .SetRequestHeader "Content-type", "multipart/form-data; boundary=" & strBoundary 'NEW LINE
.Send bytPayLoad '''SEND FILE
MsgBox bytPD
If Err.Number <> 0 Then
strStatus = Err.Description & " (" & Err.Number & ")"
Else
strStatus = .StatusText & " (" & .Status & ")"
End If
If .Status = "400" Then strResponse = .ResponseText
If .Status = "401" Then strResponse = .ResponseText
If .Status = "200" Then strResponse = .ResponseText
End With
End Sub
答案 0 :(得分:2)
我找到了解决方案。这是我的逻辑:
使用卷曲,您可以使用以下方式发送文件和参数:
curl -XPOST '127.0.0.1:8000' -F 'file=@/Users/luca/Desktop/img.png' -F 'id=123456'
在这种情况下,您可以看到:
如果您在这样的监听模式下使用netcat ...
nc -l -p 8000
这意味着它正在监听localhost = 127.0.0.1的端口8000上的任何内容(我使用的是Mac版本的Netcat。您可能需要更改一些参数才能使其工作)。
因此:在侦听模式下启动netcat,启动上一个curl命令,您将看到整个POST数据包。现在您知道它的制作方法了。 看起来像这样:
POST / HTTP/1.1
Host: 127.0.0.1:8000
User-Agent: curl/7.54.0
Accept: */*
Content-Length: 427
Expect: 100-continue
Content-Type: multipart/form-data; boundary=------------------------60cd44468072da0e
--------------------------60cd44468072da0e
Content-Disposition: form-data; name="file"; filename="img.png"
Content-Type: application/octet-stream
?PNG
IHDR
??w&sRGB???gAMA??
?a pHYs??(J?IDAT(Scd``??D&(MU?
?bg?ܞ?IEND?B`?
--------------------------60cd44468072da0e
Content-Disposition: form-data; name="id"
123456
--------------------------60cd44468072da0e--
现在您知道工作包的制作方式,就可以复制它了。
对于标题使用:
httpServer.SetRequestHeader "Content-type", "multipart/form-data; boundary=------------------------2deddc24cb2a8ca2;"
(边界是一种分隔符。请在Google上进行检查)
然后,您可以构建POST请求的正文:
body = "--" & "------------------------2deddc24cb2a8ca2" & vbCrLf & _
"Content-Disposition: form-data; name=""file""; filename=""" & objFSO.GetFileName(objFile) & """" & vbCrLf & _
"Content-Type: application/octet-stream" & vbCrLf & vbCrLf & _
FILE_CONTENT & vbCrLf & _
"--" & "------------------------2deddc24cb2a8ca2" & vbCrLf & _
"Content-Disposition: form-data; name=""id""" & vbCrLf & vbCrLf & _
ID & vbCrLf & _
"--" & "------------------------2deddc24cb2a8ca2" & "--" & vbCrLf & vbCrLf
注意:
问题: 您在下面发布的代码应打开一个流,将主体的第一部分编写为字符串,写入文件的BINARY内容,将主体的最后部分编写为字符串。
将字符串和二进制数据组合起来对我不起作用:我只能发送二进制或文本文件。如果我将二进制内容转换为字符串,则远程服务器将获得损坏(不同)的文件...
示例(仅二进制文件):
Set stream = CreateObject("ADODB.Stream")
stream.Mode = 3
stream.Type = 1
stream.Open
stream.LoadFromFile("C:\Users\Luca\Desktop\i.png")
Set objHttp = CreateObject("MSXML2.ServerXMLHTTP")
objHttp.Open "POST", "http://10.0.2.2:8000/", False
objHttp.Send stream.Read(stream.Size)
示例(仅文本文件)
Set stream = CreateObject("ADODB.Stream")
stream.Mode = 3
stream.Type = 2
stream.Open
stream.LoadFromFile("C:\Users\Luca\Desktop\i.txt")
readBinaryFile = stream.Read
requestBody = "--------------------------2deddc24cb2a8ca2" & vbCrLf & _
"Content-Disposition: form-data; name=""file""; filename=""" & objFSO.GetFileName(objFile) & """" & vbCrLf & _
"Content-Type: application/octet-stream" & vbCrLf & vbCrLf & _
readBinaryFile & vbCrLf & _
"--------------------------2deddc24cb2a8ca2" & vbCrLf & _
"Content-Disposition: form-data; name=""id""" & vbCrLf & vbCrLf & _
ID & vbCrLf & _
"--------------------------2deddc24cb2a8ca2--" & vbCrLf & vbCrLf
正如我告诉你的那样,如果将流更改。将类型从2更改为1(对于Binary),将结束发送损坏的文件。
我的解决方案是将参数作为额外的Header值发送: 示例:
httpServer.Open "POST", "http://10.0.2.2:8000/", False
httpServer.SetRequestHeader "Content-type", "application/octet-stream;"
httpServer.SetRequestHeader "Id", ID
httpServer.Send stream.Read(stream.Size)
现在我可以发送参数(Id)和二进制文件...
注意:使用内容类型:application / octet-stream ,您也可以发送未知文件扩展名