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

时间:2019-03-24 09:25:44

标签: excel vba api web-scraping xmlhttprequest

更新:已解决->在下面寻找答案。

更新: 在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模型中分析数据。 我尝试了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

1 个答案:

答案 0 :(得分:0)

已解决,最后...

所以我找到了答案。 重新分析Postman响应后,我发现JSON响应实际上是作为gzip编码的响应处理的。根本与MSXML2.XMLHTTP库不兼容。

因此,要解决此问题,我所做的就是改用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