如何使用 WinHTTPRequest 在 Excel 中发送带有 VBA 的表单数据 POST 请求

How to send a form-data POST request with VBA in Excel using WinHTTPRequest

我正在使用 FastAPI 构建一个 API,它必须可以从 Excel VBA 访问。 FastAPI 的 OAuth2 身份验证机制要求我发送 "form-data" POST 请求,但我不知道如何使用 VBA 中的 WinHTTPRequest 来执行此操作。

我已经有一个从 API 获取普通 JSON 的函数,但这是一个 GET 函数,我不确定在何处指定 "form-data" 部分正文,也没有放置用户名和密码键值对的位置。

这是一个简单的 VBA GET 处理一些错误。我将如何修改它以使用用户名和密码字段进行表单数据 POST?

Public Function getreq(url As String)
    Dim req As WinHttpRequest
    Dim JsonString As String
    Dim jp As Object
    Dim resp As String
    Dim errorstring As String

    Set req = New WinHttpRequest
    ' req.SetRequestHeaderxxx ?
    ' this is where auth will go via POST form-data username and password?
    req.Open "GET", url
    On Error GoTo errhand:
        req.Send
        resp = req.ResponseText
        If resp = "Internal Server Error" Then
            resp = "{'error': 'Internal server error'}"
        End If
        getreq = resp
    Exit Function

errhand:

    Select Case Err.Number
        Case -2147012894 'Code for Timeout
            getreq = "{'error': 'Request timeout'}"
        Case -2147012891 'Code for Invalid URL
            getreq = "{'error': 'Bad url'}"
        Case -2147012867 'Code for Invalid URL
            getreq = "{'error': 'Cannot establish connection'}"
        Case Else 'Add more Errorcodes here if wanted
            errorstring = "Errornumber: " & Err.Number & vbNewLine & "Errordescription: " & Error(Err.Number)
            getreq = "{'error': '" & errorstring & "'}"
    End Select
End Function

而不是打开一个 GET 请求 req.Open "GET", url 你需要打开一个 POST

req.Open "POST", url, False

然后您可以使用 setRequestHeader 设置您要发送的内容类型以及您在 return 中接受的内容。

req.setRequestHeader "Content-Type", "multipart/form-data"
req.setRequestHeader "Accept", "application/xml"

对于授权,您还需要创建一个请求 header。这取决于您的 API 使用什么。

req.setRequestHeader "Authorization:", "Bearer " & EncodeBase64("Your-access-token")

你终于发送请求了

req.send (YourData)

查看 this answer,其中显示了 multipart/form-data 的数据结构是如何生成的。


如果 WinHTTPRequest 不起作用,我建议尝试以下方法

Set objHttp = CreateObject("MSXML2.ServerXMLHTTP.6.0")
URL = "https:///commercial/payments-processing/v1/test/token"
objHttp.Open "POST", URL, False
objHttp.setRequestHeader "Content-Type", "multipart/form-data"
objHttp.setRequestHeader "Accept", "application/xml"
objHttp.setRequestHeader "Authorization:", "Bearer [Access Token]"
objHttp.send (strPaylodValue)
strResponseStatus = objHttp.Status
strResponseText = objHttp.ResponseText
strResponseText = CStr(strResponseText)