带有JSON主体的API的VBA HTTP请求返回空数组(Excel中的MSXML2.XMLHTTP)

问题描述 投票:1回答:1

更新:已解决 - >请在下面查看答案。

更新:在Microsoft文档中我可以看到,当使用Async = false调用open方法时,如果“协议栈超时”,响应可能不会返回,但是我无法读取超时定时器。 https://docs.microsoft.com/en-us/previous-versions/windows/embedded/ms931177%28v%3dmsdn.10%29不确定它是否相关。

我正在尝试通过VersionOne查询API检索JSON响应对象。当我尝试在VBA中读取responseText时,我收到一个空数组,但完全相同的请求从PostMan返回正确的数据。我得到HTTP 200代码响应,但响应正文中没有数据。

在VBA和Excel中执行此操作的原因是数据需要在预先存在的Excel模型中进行分析。我尝试了不同的auth可能性,OAUTH和Basic。

这是VBA代码

Option Explicit
Sub Test_LateBinding()

    Dim objRequest As Object
    Dim strUrl As String
    Dim strResponse As String
    Dim body As String
    Dim strResponseHeaders As String
    Dim allResponseHeader As String

    Set objRequest = CreateObject("MSXML2.XMLHTTP")
    strUrl = "https://endpoint"
    body = " { ""from"": ""Epic"",""select"": []}"    
    'with basic'
    With objRequest
        .Open "GET", strUrl, False, "XXXX", "XXXX"
        .SetRequestHeader "Content-Type", "application/json"
        .Send body
        strResponseHeaders = .StatusText
        strResponse = .ResponseText
        allResponseHeader = .GetAllResponseHeaders
    End With
    Debug.Print body
    Debug.Print allResponseHeader
    Debug.Print strResponse

End Sub

这是我的控制台输出:

OK
Content-Type: application/json; charset=utf-8
Content-Length: 2
X-Content-Type-Options: nosniff
V1-MemberID: skatteministeriet/120267
Strict-Transport-Security: max-age=31536000; includeSubdomains
X-Robots-Tag: noindex
VersionOne: Ultimate/19.0.3.29; 0
X-Instart-Request-ID: 3912039762705832388:SEN01-NPPRY25:1553377406:0

[]

这是PostMan响应标题:PostMan response headers

这是URL和请求JSON正文:URL and request body

excel vba api web-scraping xmlhttprequest
1个回答
0
投票

最后解决了......

所以我找到了答案。在重新分析Postman响应之后,我发现JSON响应实际上是作为gzip编码响应传递的。这与MSXML2.XMLHTTP lib完全不兼容。

因此,为了解决这个问题,我所做的只是使用WinHttp.WinHttpRequest.5.1 lib,这基本上是新的。不需要对代码进行其他更改。

所以对于那些使用MSXML2.XMLHTTP或WinHTTPserver.6.0 lib的人来说,转到更新的库:)


Option Explicit
Sub Test_LateBinding()

    Dim objRequest As Object
    Dim strUrl As String
    Dim strResponse As String
    Dim body As String
    Dim strResponseHeaders As String
    Dim allResponseHeader As String

    Set objRequest = CreateObject("WinHttp.WinHttpRequest.5.1")
    strUrl = "https://endpoint"
    body = " { ""from"": ""Epic"",""select"": []}"    
    'with basic'
    With objRequest
        .Open "GET", strUrl, False, "XXXX", "XXXX"
        .SetRequestHeader "Content-Type", "application/json"
        .Send body
        strResponseHeaders = .StatusText
        strResponse = .ResponseText
        allResponseHeader = .GetAllResponseHeaders
    End With
    Debug.Print body
    Debug.Print allResponseHeader
    Debug.Print strResponse

End Sub
© www.soinside.com 2019 - 2024. All rights reserved.