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 information they have provided
The query must be sent as a "multipart / form-data" html form using the "POST" method.
Input parameters:
ssid : (type "text") user's ScreenScraper identifier
sspassword : (type "text") ScreenScraper password of the user
gameid : (type "text") numerical identifier of the game on ScreenScraper
or
romid ( "text") numeric ID of the Roma on ScreenScraper
to propose a textual info:
modiftypeinfo ( "text") type of information sent (see list "modiftypeinfo")
modifregion ( "text"
<html>
<head>
<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
<META http-equiv="content-language" content="fr">
<title></title>
</head>
<body>
<form name="myform" id="myform" method="post" enctype="multipart/form-data" action="https://www.screenscraper.fr/api/botProposition.php?ssid=xxx&sspassword=yyy">
<input type="text" name="gameid" value="3">
<input type="text" name="modiftypeinfo" value="description">
<input type="text" name="modifregion" value="">
<input type="text" name="modiflangue" value="fr">
<input type="text" name="modifversion" value="">
<input type="text" name="modiftexte" value="ici, le synopsis du jeu ! ne pas valider, c'est un test ;)">
<input type="text" name="modifsource" value="botProposition / source de l'info">
<input type="submit" value="envoyer">
</form>
<script>
document.getElementById("myform").submit();
</script>
</body>
</html>
This is the code I have put together:
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 "Content-Type", "text/html; charset=UTF-8"
xmlhttp.setRequestHeader "enctype", "multipart/form-data"
'~~> Send the data as name/value pairs
SendString = "&type=text&name=gameid&value=185882"
SendString = SendString & "&type=text&name=modiftypeinfo&value=genres"
SendString = SendString & "&type=text&name=modiftexte&value=Sports"
SendString = SendString & "&type=submit&value=envoyer"
Debug.Print SendString
xmlhttp.send SendString
response = xmlhttp.responseText
MsgBox response
Set xmlhttp = Nothing
End Sub
I am not sure what to do with this part: form name="myform" id="myform"
in the instructions and I am not sure if my request via building a string is even anywhere near correct.
You won't be able to run without a login, it will return a password invalid error.
With curl, you add each separate multipart with one -F (or --form ) flag and you then continue and add one -F for every input field in the form that you want to send. The above small example form has two parts, one named 'person' that is a plain text field and one named 'secret' that is a file.
Multipart form data: The ENCTYPE attribute of <form> tag specifies the method of encoding for the form data. It is one of the two ways of encoding the HTML form. It is specifically used when file uploading is required in HTML form. It sends the form data to server in multiple parts because of large size of file.
Multipart/Form-Data is a popular format for REST APIs, since it can represent each key-value pair as a “part” with its own content type and disposition. Each part is separated by a specific boundary string, and we don't explicitly need Percent Encoding for their values.
The main advantage to using multipart/form-data for sending a file is that it will work automatically in both frontend and backend. You don't have to do any special handling. All files are binary even if they should only contain text.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With