MS Access中的异步HTTP POST请求

Ada*_*cha 6 rest ms-access asynchronous access-vba

我在访问项目中使用异步HTTP请求类.作者只补充说GET.因此,我试图POST在课堂上添加功能.

我将以下代码添加到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
Run Code Online (Sandbox Code Playgroud)

在调用上面的子时,我在我的表单中起诉下面的代码.

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
Run Code Online (Sandbox Code Playgroud)

见上面一行,我提到过这就是执行停止的地方.任何帮助表示赞赏.我对编程比较陌生.我错误地称这个子?括号丢失了吗?

我能够GET正确执行,如班级作者所示.在POST我加入,不工作

编辑1:回复Gord Thompson,使这个Q重复:问题#1463635用于ASP,我要求VBA中的Access是完全不同的东西.

编辑2:我在Access项目中添加了以下引用.

参考

kri*_* KM 4

您是“发布”还是“获取”并不重要。在实现此操作之前,您需要了解一些事情。

  1. MS Access vba 是单线程的,因此除非使用外部 DLL 或很少可用的 hack,否则不可能并行执行或线程执行。
  2. 为了实现“异步 HTTP 请求”,或者换句话说,告诉 VBA 不要等待 HTTP 回复,您需要对回调类进行一些修改。

其工艺流程如下:

  1. 创建您的 HTTP 请求
  2. 添加所有参数和其他所有内容
  3. 分配回调函数
  4. 使用 [varAsyn]=True 发送/打开 MSXML2.XMLHTTP
  5. 让vba继续处理其他代码,一旦收到http回复,回调类将触发一个事件。

重要提示:回调函数将是一个类,并且该类需要 hack。

【STEP1:准备回调类】

在 VBA 中创建新的类模块,使用以下代码将其命名为 HTTP_HANDLER_CLASS:

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
Run Code Online (Sandbox Code Playgroud)

[第2步:修改/破解回调类]

  1. 现在导出该类并将其保存在桌面上作为 HTTP_HANDLER_CLASS.cls
  2. 在任何文本编辑工具中打开导出的类
  3. 添加:“Attribute OnReadyStateChange.VB_UserMemId = 0”位于子“Sub OnReadyStateChange()”下方在此输入图像描述
  4. 返回 VBA 并导入类(覆盖或删除现有的)

这将使 OnReadyStateChange() 成为我们想要的默认函数,到目前为止,您已经完成了最重要的部分:

[步骤 3:发送请求此示例使用 SOAP 操作] 假设您可以使用 Web 服务“CallingServiceName”,该服务采用两个参数 iEmail、iPassword,并在登录成功与否时返回一个字符串。

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's 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
Run Code Online (Sandbox Code Playgroud)

[结果] 结果

哦,顺便说一句,Microsoft XML v3 就足够了。 在此输入图像描述

上面的示例使用 SOAP 版本,但您可以使用任何方法。请告诉我这是否有帮助。