在 MS Access VBA 中使用 MSXML2.XMLHTTP 返回空白正文响应

问题描述

我有一个 MS Access 应用程序,它向网页发送一个唯一标识符,并且该页面应该以名字、姓氏和出生日期进行响应。

这最近被打破了,我最好的跟踪根本原因是请求从网页返回一个空白的正文,我们的代码使用正文来解析返回的数据。没有正文,没有解析。

在我逐步执行代码时没有错误。我和一个同事总共有 3 天的时间来解决这个问题。我们找到了突破点,但没有解决问题的线索。

以下是应该发生的情况的概述,以及故障排除导致我们走向何处的详细信息:

  1. 点击访问表单上的“查找按钮”,验证身份证号码格式
    Dim sHTML as String
    If ValidIDFormat(Me.ID.Value & "") Then
        sHTML = GetDOCData(Me.ID.Value)

(我会省去“ValidIDFormat”背后的代码,因为这不是问题的根源)

  1. GetDocData(以上)是(我认为?)问题。 GetDocData 是一个函数,它接受 ID 号并将其作为请求发送到网页,如下所示:

    Public Function GetDOCData(aID As String) As String
    Const SUB_NAME As String = "GetDOCData"
    On Error GoTo ErrCond
    Dim myurl As String
    Dim t As Single
    Dim TimedOut As Boolean
    Dim Tries As Integer
    
    Dim xHTTP As MSXML2.xmlhttp
    Set xHTTP = New MSXML2.xmlhttp
    myurl = "http://doclookup.com/GCA00P00/WIQ1/WINQ000"  'Upon inspecting the webpage,I found /GCA00P00/WIQ1/WINQ000 corresponds to the webpage's Form Method "Post" Action ( <form method="post" action="/GCA00P00/WIQ1/WINQ000"> )
TryAgain:
    xHTTP.Open "POST",myurl,True
    xHTTP.setRequestHeader "Accept","text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8"
    xHTTP.setRequestHeader "Accept-Encoding","gzip,deflate"
    xHTTP.setRequestHeader "Accept-Language","en-US,en;q=0.9,ru;q=0.8"
    xHTTP.setRequestHeader "Cache-Control","max-age=0"
    xHTTP.setRequestHeader "Content-Length","213"
    xHTTP.setRequestHeader "Host","doclookup.com"
    xHTTP.setRequestHeader "Origin","http://doclookup.com"
    xHTTP.setRequestHeader "Proxy-Connection","keep-alive"
    xHTTP.setRequestHeader "Referer","http://doclookup.com/GCA00P00/WIQ1/WINQ000"
    xHTTP.setRequestHeader "Upgrade-Insecure-Requests","1"
    xHTTP.setRequestHeader "Content-Type","application/x-www-form-urlencoded"
    xHTTP.send "K01=WINQ000&DFH_STATE_TOKEN=&DFH_MAP_STATE_TOKEN=&M00_LAST_NAMEI=&M00_FirsT_NAMEI=&M00_MID_NAMEI=&M00_NAME_SUFXI=&M00_dobCCYYI=&M00_ID_FLD1I=" & left(aID,2) & "&M00_ID_FLD2I=" & Mid(aID,3,1) & "&M00_ID_FLD3I=" & Right(aID,4) & "&M00_MISCID_FLD1I=&M00_MISCID_FLD2I="
    t = Timer
    Tries = 1
    do while (True)
        DoEvents
        If ((Timer - t) > 5) Then
            TimedOut = True
            xHTTP.abort
            GetDOCData = ""
            Exit Do
        End If
        If (xHTTP.ReadyState = 4) Then
            If (xHTTP.Status <> 200) Then
                If (Tries < 3) Then
                    Tries = Tries + 1
                    xHTTP.abort
                    GoTo TryAgain
                Else
                    TimedOut = True
                    xHTTP.abort
                    GetDOCData = ""
                    Exit Do
                End If
            Else
                TimedOut = False
                GetDOCData = xHTTP.responseText
                Debug.Print xHTTP.responseText
                Exit Do
            End If
        End If
        DoEvents
    Loop
    Set xHTTP = nothing
    Exit Function
ErrCond:
    EventLogging AppSession.UserName,MSG_TYPE_ERROR,Err.Number,Err.Description,MOD_NAME & "." & SUB_NAME,AppSession.AppSilent
    Set xHTTP = nothing
End Function

Debug.Print 响应的输出

<!DOCTYPE html>
<html><head>
<Meta http-equiv="Pragma" content="no-cache"/>
<Meta http-equiv="Expires" content="-1"/>
<Meta http-equiv="CacheControl" content="no-cache"/>
<Meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<link rel="shortcut icon" href="data:;base64,iVBORw0KGgo="/>

<script>

(function(){
window["bobcmn"] = "11111110101010200000005200000005200000001282ff3ca2200000096300000029application%2fx%2dwww%2dform%2durlencoded300000000300000006/TSPD/300000008TSPD_101300000004http3000000b008f09154e8ab2000c866a39c833f24d99d84e7901aac5a13c0c8ad737654afb25b96b27aba9f9b9008c421cc190a28006d5c954f4b5b362cf850d4f70b2a1ff8e8fcfb526acb91a5740a4c0e36f7d3e7e790a51f2ffbaf98300000107K01%3dWINQ000%26DFH_STATE_TOKEN%3d%26DFH_MAP_STATE_TOKEN%3d%26M00_LAST_NAMEI%3d%26M00_FirsT_NAMEI%3d%26M00_MID_NAMEI%3d%26M00_NAME_SUFXI%3d%26M00_dobCCYYI%3d%26M00_ID_FLD1I%3d95%26M00_ID_FLD2I%3db%26M00_ID_FLD3I%3d1929%26M00_MISCID_FLD1I%3d%26M00_MISCID_FLD2I%3d200000000";

window.OYm=!!window.OYm;try{(function(){(function(){var S={decrypt:function(S){try{return JSON.parse(function(S){S=S.split("l");var I="";for(var l=0;l<S.length;++l)I+=String.fromCharCode(S[l]);return I}(S))}catch(l){}}};return S={configuration:S.decrypt("123l34l97l99l116l105l118l101l34l58l34l110l111l34l44l34l100l101l98l117l103l103l105l110l103l34l58l34l110l111l34l44l34l109l111l100l117l108l101l49l34l58l34l101l110l97l98l108l101l100l34l44l34l109l111l100l117l108l101l50l34l58l34l101l110l97l98l108l101l100l34l44l34l109l111l100l117l108l101l51l34l58l34l101l110l97l98l108l101l100l34l44l34l109l111l100l117l108l101l52l34l58l34l101l110l97l98l108l101l100l34l125")}})();
var iS=91;try{var JS,LS,OS=_(200)?0:1,ZS=_(567)?0:1,S_=_(300)?0:1;for(var __=(_(912),0);__<LS;++__)OS+=_(989)?1:2,ZS+=(_(404),2),S_+=(_(437),3);JS=OS+ZS+S_;window.jj===JS&&(window.jj=++JS)}catch(i_){window.jj=JS}var o_=!0;function J(S){var I=arguments.length,l=[];for(var Z=1;Z<I;++Z)l.push(arguments[Z]-S);return String.fromCharCode.apply(String,l)}
function z_(S){var I=69;!S||document[L(I,187,174,184,167,177,185,190,152,166,170)]&&document[J(I,170)]!==J(I,170)||(o_=!1);return o_}function L(S){var I=arguments.length,l=[],Z=1;while(Z<I)l[Z-1]=arguments[Z++]-S;return String.fromCharCode.apply(String,l)}function _i(){}z_(window[_i[O(1086763,iS)]]===_i);z_(typeof ie9rgb4!==O(1242178186108,iS));
z_(RegExp("\x3c")[O(1372114,iS)](function(){return"\x3c"})&!RegExp(O(42798,iS))[O(1372114,iS)](function(){return"'x3'+'d';"}));
var ii=window[L(iS,188,207,195,160,209,192,201,207)]||RegExp(J(iS,200,202,189,196,215,191,205,191),O(-73,iS)](window["\x6e\x61vi\x67a\x74\x6f\x72"]["\x75\x73e\x72A\x67\x65\x6et"]),ji=+new Date+(_(283)?392128:6E5),Ji,li,si,SI=window[J(iS,206,175,208,207)],iI=ii?_(896)?24437:3E4:_(789)?7473:6E3;
document[L(iS,205)]&&document[L(iS,205)](L(iS,199,212,194,192),function(S){var I=87;document[L(I,203,170,188)]&&(document[J(I,188)]===O(1058781896,I)&&S[J(I,171,204,187)]?si=!0:document[J(I,188)]===L(I,188)&&(Ji=+new Date,si=!1,II()))});function II(){if(!document[J(33,146,150,134,147,154,116,141,132,149,144,147)])return!0;var S=+new Date;if(S>ji&&(_(848)?582451:6E5)>S-Ji)return z_(!1);var I=z_(li&&!si&&Ji+iI<S);Ji=S;li||(li=!0,SI(function(){li=!1},_(257)?0:1));return I}II();var jI=[_(425)?18598439:17795081,_(80)?2147483647:27611931586,_(166)?1983416588:1558153217];
function JI(S){var I=35;S=typeof S===O(1743045641,I)?S:S[J(I,151,118,140,145,138)](_(696)?24:36);var l=window[S];if(!l[L(I,138)])return;var Z=""+l;window[S]=function(S,I){li=!1;return l(S,I)};window[S][J(I,138)]=function(){return Z}}for(var LI=(_(728),0);LI<jI[L(iS,195)];++LI)JI(jI[LI]);z_(!1!==window[J(iS,180,200)]);window.IJ={Ll:"08d706d6c9018000e5822dadf90337bb593587216c9ab6a9c485b83578c4437a79e29efc9f34e830ff2af64ab8efa8fb630e6dd1e0826eb0daddd2bd5edfb2a1b1e82309950dfc445dbcd7cec14c66aad4477867c752f7bbeff0a97475a6bb1261632c2feef07f430cba4664d7e896295e4276a6c7e8e1303b350f2e5189a8f59b760816d0b62a13"};function O(S,I){S+=I;return S.toString(36)}
function oI(S){var I=+new Date,l;!document[J(46,159,163,129,162,157,111,154)]||I>ji&&(_(911)?801408:6E5)>I-Ji?l=z_(!1):(l=z_(li&&!si&&Ji+iI<I),Ji=I,li||(li=!0,_(609)?0:1)));return!(arguments[S]^l)}function _(S){return 55>S}(function zI(I){I&&"number"!==typeof I||("number"!==typeof I&&(I=1E3),I=Math.max(I,1),setInterval(function(){zI(I-10)},I))})(!0);})();}catch(x){}finally{ie9rgb4=void(0);};function ie9rgb4(a,b){return a>>b>>0};

})();

</script>

<script type="text/javascript" src="/TSPD/08f09154e8ab20002596bec38bbab41a56da7004c2247af39c737e1fdd1f8257d17ddc6579566094?type=10"></script>
<noscript>Please enable JavaScript to view the page content.<br/>Your support ID is:  1436304770756522234.</noscript>
</head><body>
</body></html>

我们注意到上面最后两行的“body”标签之间没有返回任何内容......

我还注意到“请启用 JavaScript...”消息,位于空标签之前。但是,如果这是根本问题,我不知道如何在 VBA 中启用 JS。我试着研究这个,但找不到任何有用的东西。

#2 和 #3 之间是断开连接的地方:

  1. 获取网页响应(上图)并检查在 Access 中输入的 ID 是否与此人的 1 条或多条记录相关 - 位于此网站中。

    If (IsSingleID(sHTML)) Then     '  "sHTML" here is the returned string from the webpage response in "GetDocData" Function above 
    Person = ParseDOCRecord(Me.ID.Value,sHTML)

'sometimes there are multiple returned values - housed in the website - for the person in question. One person can have multiple records,each given a unique ID. There's a different section of code,and different parsing,if multiple records/multiple IDs are returned.

IsSingleID 是一个函数定义如下


    Public Function IsSingleID(aHTML As String) As Boolean
    Const SUB_NAME As String = "IsSingleID"
    On Error GoTo ErrCond
    Dim doc As New MSHTML.HTMLDocument
    Dim o As Variant
    IsSingleID = False
    doc.Body.innerHTML = aHTML
    For Each o In doc.getElementsByTagName("h2")
        If (Trim(o.innerText) = "Person information") Then
            IsSingleID = True
            Exit For
        End If
    Next
    Set doc = nothing
    Exit Function
ErrCond:
    EventLogging AppSession.UserName,AppSession.AppSilent
End Function

代码在这里退出! doc.getElementsByTagName("h2") 中没有“o” 这可能是因为“ doc.Body.innerHTML = aHTML ”返回一个空白正文?

我尝试向“aHTML”变量添加一个监视,以确认网页响应 (sHTML) 的哪些部分被发送到上述函数中的“aHTML”变量。但是变量/响应对于观察窗口来说太长了。

无论如何,运行永远不会到达“ParseDOCRecord”函数


    If (IsSingleID(sHTML)) Then    
    Person = ParseDOCRecord(Me.ID.Value,sHTML)

运行退出“IsSingleID”函数,返回“Lookup Button”函数(#1),并进入“捕获所有”类型的消息框,硬编码返回:


MsgBox "Unable to get information from DOC site."

我正在挠头。

我们尝试过的故障排除步骤:

我们尝试更新对 Microsoft XML,v6.0 的引用并改用 MSXML2.XMLHTTP60。我的推理是可能对最新版本中的旧库进行了更改。

尝试从 URL 中删除“/GCA00P00/WIQ1/WINQ000”,并简单地使用“doclookup.com”

尝试将 doc.getElementsByTagName("h2") 中的 "h2" 标签替换为 "form" 标签,因为我注意到在检查的网页中没有看到 "h2" 标签

这是网页表单部分的代码

<form method="post" action="/GCA00P00/WIQ1/WINQ000">
    <div class="border">
      <input type="hidden" name="K01" value="WINQ000">
      <input type="hidden" name="DFH_STATE_TOKEN" value="adyqlisv">
      <input type="hidden" name="DFH_MAP_STATE_TOKEN" value="">
      <div class="pair">
        <label for="M00_LAST_NAMEI">Last Name:</label>
        <input type="text" size="18" maxlength="18" name="M00_LAST_NAMEI" value="" id="M00_LAST_NAMEI">
      </div>
      <div class="pair">
        <label for="M00_FirsT_NAMEI">First Name:</label>
        <input type="text" size="11" maxlength="11" name="M00_FirsT_NAMEI" value="" id="M00_FirsT_NAMEI">
      </div>
      <div class="pair">
        <label for="M00_MID_NAMEI">Middle Init:</label>
        <input type="text" size="1" maxlength="1" name="M00_MID_NAMEI" value="" id="M00_MID_NAMEI">
      </div>
      <div class="pair">
        <label for="M00_NAME_SUFXI">Name Suffix:</label>
        <input type="text" size="3" maxlength="3" name="M00_NAME_SUFXI" value="" id="M00_NAME_SUFXI"> (SR,JR,etc.)
      </div>
      <div class="pair">
        <label for="M00_dobCCYYI">Birth Year:</label>
        <input type="text" size="4" maxlength="4" name="M00_dobCCYYI" value="" id="M00_dobCCYYI"> (Optional,see above)
      </div>
      <div class="pair">
        <label for="M00_DIN_FLD1I">DIN:<span class="hide"> Two digit number
         </span></label>
        <input type="text" size="2" maxlength="2" name="M00_ID_FLD1I" value="" id="M00_DIN_FLD1I" onfocus="select()" onkeyup="KeyPress(this,event,2,'WINQM00.form.M00_DIN_FLD2I.focus()')">
        -
        <label for="M00_DIN_FLD2I" class="hide">One character alpha</label>
        <input type="text" size="1" maxlength="1" name="M00_ID_FLD2I" value="" id="M00_DIN_FLD2I" onfocus="select()" onkeyup="KeyPress(this,1,'WINQM00.form.M00_DIN_FLD3I.focus()')">
        -
        <label for="M00_DIN_FLD3I" class="hide">Four digit number</label>
        <input type="text" size="4" maxlength="4" name="M00_ID_FLD3I" value="" id="M00_DIN_FLD3I" onfocus="select()">
         (ID Number,format 99-A-9999,example 95-A-9876)
      </div>
      <div class="pair">
        <label for="M00_NYSID_FLD1I">NYSID:<span class="hide"> Eight digit
         number</span></label>
        <input type="text" size="8" maxlength="8" name="M00_MISCID_FLD1I" value="" id="M00_MISCID_FLD1I" onfocus="select()" onkeyup="KeyPress(this,8,'WINQM00.form.M00_MISCID_FLD2I.focus()')">
        -
        <label for="M00_MISCID_FLD2I" class="hide">One character alpha</label>
        <input type="text" size="1" maxlength="1" name="M00_MISCID_FLD2I" value="" id="M00_MISCID_FLD2I" onfocus="select()">
         (For InterDepartmental Use Only; MISC ID Number)
      </div>
      <div class="aligncenter ">
        <input type="submit" value="Submit">
        <input type="button" onclick="javascript: location.href = location.href;" value="Reset">
      </div>
    </div>
  </form>

我错过了什么?

我希望我已经用适当的细节解释了这一点...

我怎样才能让这个请求再次返回数据?


根据下面的评论/评论线程跟进...

我在网站(不是应用程序中的)上搜索了一条记录,以便从网页的“网络”选项卡生成响应日志。 DIN # 18B3079 响应截图如下:

Response Header of Lookup

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)