使用VBS发送文件和参数HTTP Post

时间:2018-05-10 01:36:50

标签: http vbscript msxml

我是新工作的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

1 个答案:

答案 0 :(得分:2)

我找到了解决方案。这是我的逻辑:

使用卷曲,您可以使用以下方式发送文件和参数:

curl -XPOST '127.0.0.1:8000' -F 'file=@/Users/luca/Desktop/img.png' -F 'id=123456'

在这种情况下,您可以看到:

  • IP = 127.0.0.1(localhost)
  • 端口= 8000
  • 文件名= img.png
  • 参数=“ 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

注意:

  • 在正文中您可以看到每个边界在开头都有一个附加的“-” 字符串(实际上我写了“-”&“ ------- ----------------- 2deddc24cb2a8ca2“ ),并在最后一个边界的末尾附加一个”-“
  • 标头必须在vbs的行末具有“;” ,即使在先前捕获的POST请求中不可见也是如此。我不知道为什么。
  • 正文中的
  • FILE_CONTENT 变量是文件的内容
  • 注意每个 vbCrLf (行的结尾),否则POST请求可能无效。

问题: 您在下面发布的代码应打开一个流,将主体的第一部分编写为字符串,写入文件的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 ,您也可以发送未知文件扩展名