Asynchronous HTTP POST request in MS Access

I am using the Asynchronous HTTP Request class in my access project. The author added only GET . Therefore, I am trying to add a POST class to a class.

The following code I added to the class

 Public Sub PostRequest(serviceURL As Variant, Optional apiBody As String) On Error GoTo Sub_Err Set m_oXmlHttp = New MSXML2.XMLHTTP60 m_oXmlHttp.Open "POST", serviceURL, True 'this sets the onreadystatechange call back to an instance of this object 'which causes the default method HandleResponse to be called when the ready 'state changes m_oXmlHttp.onreadystatechange = Me m_oXmlHttp.send apiBody 'Error Catching Sub_Exit: Exit Sub Sub_Err: MsgBox Error$ Resume Sub_Exit End Sub 

When I called the above, I sued the code below in my form.

 Private WithEvents oAHlogin As clsAsyncHTTP Private Sub PostLoginData() Dim apiURL, apiBody As String apiURL = "myurl" apiBody = "mybody" Set oAHlogin = New clsAsyncHTTP oAHlogin.PostRequest apiURL, apiBody '*This is where the execution stops*. End Sub Private Sub oAHlogin_ResponseReady(ByVal ready As Boolean) If ready Then Debug.Print oAHlogin.GetReponseText End If End Sub 

See the line above where I mentioned. This is where execution stops. Any help is appreciated. I am relatively new to programming. Am I calling sub incorrectly? Is the parenthesis missing?

I managed to get the GET right, as shown by the author of this class. POST that I added does not work

Edit 1: Answer Gord Thompson, making this Q as a duplicate: Question No. 1463635 for ASP, I ask you to access VBA, which are completely different things.

Edit 2: I added the following links to my Access project.

References

+5
source share
3 answers

It doesn't matter if you are "post" ing or "GET" ing. Before this happens, you need to understand something.

  • MS Access vba is single-threaded, so parallel or threaded execution is not possible, except for using external DLLs or small available hacks.
  • In order to achieve “Asynchronous HTTP requests” or, in other words, tell VBA not to wait for an HTTP response, you need to hack a little callback class.

The process flow is as follows:

  • Create your HTTP request
  • add all parameters and everything else
  • assign callback function
  • Submit / Open MSXML2.XMLHTTP with [varAsyn] = True
  • let vba continue to work on another code, as soon as an http response is received, the callback class will fire an event.

It is important . The callback function will be a class, and this class needs a hack.

[STEP1: preparing callback class]

Create a new class module in VBA, name it HTTP_HANDLER_CLASS with the following code:

 Option Compare Database Option Explicit Dim m_xmlHttp As MSXML2.XMLHTTP Public Sub Initialize(ByRef xmlHttpRequest As MSXML2.XMLHTTP) Set m_xmlHttp = xmlHttpRequest End Sub Sub OnReadyStateChange() If m_xmlHttp.ReadyState = 4 Then If m_xmlHttp.status = 200 Then Debug.Print m_xmlHttp.responseText Else 'Error happened End If End If End Sub 

[STEP2: modify / hack callback class]

  • Now export the class and save it on your desktop as HTTP_HANDLER_CLASS.cls
  • Open the exported class in any text editing tool.
  • Add: "Attribute OnReadyStateChange.VB_UserMemId = 0" just below the sub-Sub SubReadyStateChange () " enter image description here
  • Go back to VBA and import the class (overwrite or delete the existing one)

This will make OnReadyStateChange () the default function we wanted to have, and so far you have performed the most important role:

[Step 3: sending requests in this example uses the SOAP action] Suppose you have access to the CallingServiceName web service, which takes two iEmail, iPassword and returns a string if the login was successful or not.

 Module level variable: Public xmlHttpRequest As MSXML2.XMLHTTP Public Function HTTP_TEST() On Error GoTo FailedState If Not xmlHttpRequest Is Nothing Then Set xmlHttpRequest = Nothing Dim MyXmlHttpHandler As HTTP_HANDLER_CLASS 'our hacked call back class Set xmlHttpRequest = New MSXML2.XMLHTTP Dim sURL As String Dim sEnv As String sURL = "http://mydomain.co.uk/mywebsite/myservices.asmx?op=CallingServiceName" sEnv = "<?xml version=""1.0"" encoding=""utf-8""?>" sEnv = sEnv & "<soap:Envelope xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" xmlns:xsd=""http://www.w3.org/2001/XMLSchema"" xmlns:soap=""http://schemas.xmlsoap.org/soap/envelope/"">" sEnv = sEnv & " <soap:Body>" sEnv = sEnv & " <CallingServiceName xmlns=""http://mydomain.co.uk/"">" sEnv = sEnv & " <iEmail>username</iEmail>" sEnv = sEnv & " <iPassword>mypassword</iPassword>" sEnv = sEnv & " </CallingServiceName>" sEnv = sEnv & " </soap:Body>" sEnv = sEnv & "</soap:Envelope>" ' Now create an instance of our call-back class Set MyXmlHttpHandler = New HTTP_HANDLER_CLASS MyXmlHttpHandler.Initialize xmlHttpRequest ' Now attach the call-back class to our request, so whenever the request state changes, callback classs default function will fire. xmlHttpRequest.OnReadyStateChange = MyXmlHttpHandler ' seal the envelop and send it xmlHttpRequest.Open "Post", sURL, True ' here set varAsyn=true xmlHttpRequest.setRequestHeader "Host", "mydomain.co.uk" xmlHttpRequest.setRequestHeader "Content-Type", "text/xml; charset=utf-8" xmlHttpRequest.setRequestHeader "soapAction", "http://mydomain.co.uk/CallingServiceName" xmlHttpRequest.Send sEnv Debug.Print "Controller finished job" ' this is for you to realize vba will continue to work, the http result will be fired whenever the onstateChanges. Exit Function FailedState: 'MsgBox err.Number & ": " & err.description End Function 

[Result] Result

oh btw, Microsoft XML v3 is enough for this. enter image description here

The above example uses the SOAP version, but you can use any method. Please let me know if this helped.

+2
source

You need to set the headers. At a minimum, you need to add this line to your class before you call .Send

 m_oXmlHttp.setRequestHeader "Content-Type", "application/x-www-form-urlencoded" 
+1
source

After messing up the code a bit more, I found that when creating the asynchronous POST there were several subtle changes needed for the code in the answer to the question that was previously marked as a duplicate. This is the code that ended up working for me:

 ' VBA project reference required: ' Microsoft XML, v6.0 Dim postData As String postData = "word1=hello&word2=world" Dim objXmlHttp As New MSXML2.XMLHTTP objXmlHttp.Open "POST", "http://localhost:8080/postTest.php", True objXmlHttp.setRequestHeader "Content-Type", "application/x-www-form-urlencoded" objXmlHttp.setRequestHeader "Content-Length", Len(postData) objXmlHttp.send postData Set objXmlHttp = Nothing 
+1
source

All Articles