我在我的 Access 项目中使用Asynchronous HTTP Request Class
作者只添加了GET。因此,我试图将POST功能添加到该类中。

我添加到类的以下代码

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

调用上述子程序时,我在表单中使用以下代码。
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

参见上面的行,我已经提到了这是执行停止的地方。任何帮助表示赞赏。我是编程新手。我打错电话了吗?括号缺失了吗?

我能够正确执行GET,如该类的作者所示。我添加的POST不起作用

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

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

rest - MS Access中的异步HTTP POST请求-LMLPHP

最佳答案

无论您是“发布”还是“获取”,都没有关系。做到这一点之前,您需要了解的东西很少。

  • MS Access vba是单线程的,因此,除非使用外部DLL或几乎没有可用的技巧,否则无法并行执行或执行线程执行。
  • 为了实现“异步HTTP请求”或换句话说,要告诉VBA不要等待HTTP应答,您需要对回调类进行一些修改。

  • 处理流程如下:
  • 创建您的HTTP请求
  • 添加所有参数以及其他所有内容
  • 分配一个回调函数
  • 使用[varAsyn] = True
  • 发送/打开MSXML2.XMLHTTP
  • 让vba继续处理其他代码,一旦收到http答复,则回调类将触发一个事件。

  • 重要:回调函数将是一个类,该类需要修改。

    [STEP1:准备回调类]

    在您的VBA中创建新的Class模块,并使用以下代码将其命名为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
    

    [STEP2:修改/修改回叫类]
  • 现在导出类并将其另存为HTTP_HANDLER_CLASS.cls放在桌面中
  • 在任何文本编辑工具
  • 中打开导出的类
  • 添加:“SubOnReadyStateChange()”子项下方的“Attribute OnReadyStateChange.VB_UserMemId = 0” rest - MS Access中的异步HTTP POST请求-LMLPHP
  • 返回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
    

    [结果]
    rest - MS Access中的异步HTTP POST请求-LMLPHP

    哦,顺便说一句,Microsoft XML v3足以满足此要求。
    rest - MS Access中的异步HTTP POST请求-LMLPHP

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

    09-26 16:11
    查看更多