Need help to post multipart form data using the post method in VBA

前端 未结 2 1712
陌清茗
陌清茗 2020-12-06 08:05

I am trying to use an API to update an online database.

The API is hosted by a french site and the usage details are slim with no examples.

This is the infor

相关标签:
2条回答
  • 2020-12-06 08:46

    The structure of multipart/form-data is described in RFC7578. There is a sample:

    POST /form.html HTTP/1.1
    Host: server.com
    Referer: http://server.com/form.html
    User-Agent: Mozilla
    Content-Type: multipart/form-data; boundary=-------------573cf973d5228
    Content-Length: 288
    Connection: keep-alive
    Keep-Alive: 300
    
    
    ---------------573cf973d5228
    Content-Disposition: form-data; name="field"
    
    text
    ---------------573cf973d5228
    Content-Disposition: form-data; name="file"; filename="sample.txt"
    Content-Type: text/plain
    
    Content file
    ---------------573cf973d5228--
    

    Try the below code to make POST XHR:

    Sub POST_multipart_form_data()
    
        Dim oFields As Object
        Dim sBoundary As String
        Dim sPayLoad As String
        Dim sName As Variant
    
        Set oFields = CreateObject("Scripting.Dictionary")
        With oFields
            .Add "gameid", "3"
            .Add "modiftypeinfo", "description"
            .Add "modifregion", ""
            .Add "modiflangue", "fr"
            .Add "modifversion", ""
            .Add "modiftexte", "ici, le synopsis du jeu ! ne pas valider, c'est un test ;)"
            .Add "modifsource", "botProposition / source de l'info"
        End With
        sBoundary = String(6, "-") & Replace(Mid(CreateObject("Scriptlet.TypeLib").GUID, 2, 36), "-", "")
        sPayLoad = ""
        For Each sName In oFields
            sPayLoad = sPayLoad & "--" & sBoundary & vbCrLf
            sPayLoad = sPayLoad & "Content-Disposition: form-data; name=""" & sName & """" & vbCrLf & vbCrLf
            sPayLoad = sPayLoad & oFields(sName) & vbCrLf
        Next
        sPayLoad = sPayLoad & "--" & sBoundary & "--"
        With CreateObject("MSXML2.XMLHTTP")
            .Open "POST", "https://www.screenscraper.fr/api/botProposition.php?ssid=xxx&sspassword=yyy", False
            .setRequestHeader "Content-Type", "multipart/form-data; boundary=" & sBoundary
            .setRequestHeader "Content-Length", LenB(sPayLoad)
            .send (sPayLoad)
            MsgBox .responseText ' Erreur de login : Verifier vos identifiants !
        End With
    
    End Sub
    

    So the payload data generated by the code is as follows:

    --------CFE02291483D4B3EB3B1A92257838D94
    Content-Disposition: form-data; name="gameid"
    
    3
    --------CFE02291483D4B3EB3B1A92257838D94
    Content-Disposition: form-data; name="modiftypeinfo"
    
    description
    --------CFE02291483D4B3EB3B1A92257838D94
    Content-Disposition: form-data; name="modifregion"
    
    
    --------CFE02291483D4B3EB3B1A92257838D94
    Content-Disposition: form-data; name="modiflangue"
    
    fr
    --------CFE02291483D4B3EB3B1A92257838D94
    Content-Disposition: form-data; name="modifversion"
    
    
    --------CFE02291483D4B3EB3B1A92257838D94
    Content-Disposition: form-data; name="modiftexte"
    
    ici, le synopsis du jeu ! ne pas valider, c'est un test ;)
    --------CFE02291483D4B3EB3B1A92257838D94
    Content-Disposition: form-data; name="modifsource"
    
    botProposition / source de l'info
    --------CFE02291483D4B3EB3B1A92257838D94--
    

    Note that optional "Content-Type" header field for each part defaults to "text/plain". As you can see in comment there is login error in response for me:

    Erreur de login : Verifier vos identifiants !

    The only thing I can't get is why they specified the submission as a multipart/form-data? Even there are no files attached! It's much more easier to send the data as application/x-www-form-urlencoded using the following code:

    Sub POST_application_x_www_form_urlencoded()
    
        Dim oFields As Object
        Dim sPayLoad As String
        Dim sName As Variant
    
        Set oFields = CreateObject("Scripting.Dictionary")
        With oFields
            .Add "gameid", "3"
            .Add "modiftypeinfo", "description"
            .Add "modifregion", ""
            .Add "modiflangue", "fr"
            .Add "modifversion", ""
            .Add "modiftexte", "ici, le synopsis du jeu ! ne pas valider, c'est un test ;)"
            .Add "modifsource", "botProposition / source de l'info"
        End With
        For Each sName In oFields
            oFields(sName) = sName & "=" & EncodeUriComponent(oFields(sName))
        Next
        sPayLoad = Join(oFields.Items(), "&")
        With CreateObject("MSXML2.XMLHTTP")
            .Open "POST", "https://www.screenscraper.fr/api/botProposition.php?ssid=xxx&sspassword=yyy", False
            .setRequestHeader "Content-Type", "application/x-www-form-urlencoded"
            .setRequestHeader "Content-Length", LenB(sPayLoad)
            .send (sPayLoad)
            MsgBox .responseText ' Erreur de login : Verifier vos identifiants !
        End With
    
    End Sub
    
    Function EncodeUriComponent(sText As String) As String
        Static oHtmlfile As Object
    
        If oHtmlfile Is Nothing Then
            Set oHtmlfile = CreateObject("htmlfile")
            oHtmlfile.parentWindow.execScript "function encode(s) {return encodeURIComponent(s)}", "jscript"
        End If
        EncodeUriComponent = oHtmlfile.parentWindow.encode(sText)
    End Function
    

    And the payload data generated by the code is as follows:

    gameid=3&modiftypeinfo=description&modifregion=&modiflangue=fr&modifversion=&modiftexte=ici%2C%20le%20synopsis%20du%20jeu%20!%20ne%20pas%20valider%2C%20c'est%20un%20test%20%3B)&modifsource=botProposition%20%2F%20source%20de%20l'info
    

    The error response is the same as for the first method for me.

    0 讨论(0)
  • 2020-12-06 09:05

    Untested:

    Sub Post_Detail()
    
        Dim xmlhttp As Object, response As String, SendString As String
    
        Set xmlhttp = CreateObject("MSXML2.XMLHTTP.6.0")
    
        '~~> Indicates that page that will receive the request and the type of request being submitted
        xmlhttp.Open "POST", "https://www.screenscraper.fr/api/botProposition.php?ssid=xxx&sspassword=yyy", False
    
        '~~> Indicate that the body of the request contains form data
        xmlhttp.setRequestHeader "enctype", "multipart/form-data"
    
        '~~> Send the data as name/value pairs
        SendString = "gameid=185882" & _
                    "&modiftypeinfo=genres" & _
                    "&modiftexte=Sports"
    
        Debug.Print SendString
        xmlhttp.send SendString
    
        response = xmlhttp.responseText
        MsgBox response
    
        Set xmlhttp = Nothing
    
    End Sub
    

    I don't think the submit button is included in the POST if it has no name attribute.

    0 讨论(0)
提交回复
热议问题