• Anthem.NET 的 "BAD RESPONSE" 问题的脚本调试技巧小结


    今天解决了一位朋友使用 Anthem.NET 遇到的问题。他的代码在 Windows XP 的开发机器上反应正常,而部署到 2003 Server 的服务器上就提示 "BADRESPONSE".

    这个问题产生的原因是,Anthem 在客户端 js 中调用服务器时,会返回一个表示 js 对象的文本,在得到后,通过 eval 方式将这个对象还原。其中包括了服务器需要返回给客户端的各种信息,比如脚本,更新的 html, ViewState 等。
    如果这个 eval 出错,则会提示 'BADRESPONSE'.

    通过查看页面输出可以看到:

    JavaScript:
    function Anthem_GetResult(x) {
        
    var result = { "value"null"error"null };
        
    var responseText = x.responseText;
        
    try {
            result 
    = eval("(" + responseText + ")");
        } 
    catch (e) {
            
    if (responseText.length == 0) {
                result.error 
    = "NORESPONSE";
            } 
    else {
                result.error 
    = "BADRESPONSE";
                result.responseText 
    = responseText;
            }
        }
        
    return result;
    }

    如何分析错误呢,很明显,我们只要看看 responseText 是什么,就会知道这个文本为什么不能被 eval 估算了。
    因为 Anthem_GetResult 是由 Anthem 的 dll 动态输出的,我们需要修改这个函数的定义。
    方法是在 </body> 前面,加一段代码来修改这个函数的定义即可:

    JavaScript:
    function Anthem_GetResult(x) {
        
    var result = { "value"null"error"null };
        
    var responseText = x.responseText;
        alert(responseText);
        
    try {
            result 
    = eval("(" + responseText + ")");
        } 
    catch (e) {
            
    if (responseText.length == 0) {
                result.error 
    = "NORESPONSE";
            } 
    else {
                result.error 
    = "BADRESPONSE";
                result.responseText 
    = responseText;
            }
        }
        
    return result;
    }

    在正常情况下,alert 提示的信息如下:

    ---------------------------
    Windows Internet Explorer
    ---------------------------
    {
    "value":null,"error":null,"viewState":"/wEPDwUKMTQ4NzkxOTExMGRkLHCpj5eYh3HaWUC4wwfnI1kE8sI=","eventValidation":"/wEWAgKw5r+UAwLM9PumD2DQQ4RF4lRuD5Qz+1A07BOdo0rx","controls":{"LinkButton1":"<a onclick=\"Anthem_FireCallBackEvent(this,event,'LinkButton1','',true,'','','',true,null,null,null,true,true);return false;\" id=\"LinkButton1\" href=\"javascript:__doPostBack('LinkButton1','')\" style=\"Z-INDEX: 101; LEFT: 416px; POSITION: absolute; TOP: 96px\">Test</a>"},"script":["window.location = 'http://www.sina.com.cn';"]}
    ---------------------------
    确定   
    ---------------------------

    看上去有点乱,我们把它还原为正常的 js 代码,实际上是这样一个对象:

    JavaScript:
    {
        
    "value"null,
        
    "error"null,
        
    "viewState""/wEPDwUKMTQ4NzkxOTExMGRkLHCpj5eYh3HaWUC4wwfnI1kE8sI=",
        
    "eventValidation""/wEWAgKw5r+UAwLM9PumD2DQQ4RF4lRuD5Qz+1A07BOdo0rx",
        
    "controls": {
            
    "LinkButton1""<a onclick=\"Anthem_FireCallBackEvent(this,event,'LinkButton1','',true,'','','',true,null,null,null,true,true);return false;\" id=\"LinkButton1\" href=\"javascript:__doPostBack('LinkButton1','')\" style=\"Z-INDEX: 101; LEFT: 416px; POSITION: absolute; TOP: 96px\">Test</a>",
        },
        
    "script": [
            
    "window.location = 'http://www.sina.com.cn';"
        ]
    }

    其中 controls 是需要更新 innerHTML 的客户端控件集合,以及要更新的源代码。
    Anthem.NET 修改了常见默认控件的 Render 方法,使控件输出的 HTML 外围多了一个容器控件. 而每次回调后,都会通过这个人为添加的容器来更新其中的控件 HTML 输出。
    看如下 HTML:

    HTML:
    <span id="Anthem_LinkButton1__"><id="LinkButton1" onclick="Anthem_FireCallBackEvent(this,event,'LinkButton1','',true,'','','',true,null,null,null,true,true);return false;" href="javascript:__doPostBack('LinkButton1','')" style="Z-INDEX: 101; LEFT: 416px; POSITION: absolute; TOP: 96px">Test</a></span>

    这段代码中,span 便是 LinkButton 的容器。

    上述返回对象中的 script 属性,是在服务器端设定的,需要在返回后执行的脚本代码的集合。
    服务器端可以通过下列语句来添加脚本:

    C#:
    Anthem.Manager.AddScriptForClientSideEval("window.location = 'http://www.sina.com.cn';");

    以上分析的是 Anthem 在正常工作的情况下输出的对象,那么错误时会输出什么内容呢?下面是一个例子:

    ---------------------------
    Microsoft Internet Explorer
    ---------------------------
    <html>     <head>         <title>δʵ��÷������/title>         <style>             body {font-family:"Verdana";font-weight:normal;font-size: .7em;color:black;}              p {font-family:"Verdana";font-weight:normal;color:black;margin-top: -5px}             b {font-family:"Verdana";font-weight:bold;color:black;margin-top: -5p

    我们看到其中有乱码信息,可以判断 Anthem 是遇到了编码问题导致输出错误了。
    于是重新设定页面的编码,解决了这个问题。

    分析一下 Anthem 的实现,可以看到 Anthem 在发送请求时的设定代码:

    JavaScript:
    x.open("POST", url ? url : Anthem_DefaultURL, clientCallBack ? true : false);
    x.setRequestHeader(
    "Content-Type""application/x-www-form-urlencoded; charset=utf-8");
    x.setRequestHeader(
    "Accept-Encoding""gzip, deflate");

    其默认请求编码是 utf-8 的。

    而其输出编码,则可以通过 web.config 来定制。方法如下:

    <configuration>
        
    <system.web>
            
    <appSettings>       
                
    <add key="Anthem.ResponseEncoding" value="gb2312" />         
                
    <add key="Anthem.ResponseType" value="gb2312" />
            
    </appSettings>
        
    </system.web>
    </configuration>

    这个办法是我通过分析 Anthem 的源码发现的,奇怪的是在其文档中好像没有发现相关的说明。
    相关代码如下:

    Manager.cs (C#):
    private void ConfigureResponse(HttpResponse resp) {
        
    string contentEncoding = null;
        
    string contentType = null;
    #if V2
        contentEncoding 
    = WebConfigurationManager.AppSettings["Anthem.ResponseEncoding"];
        contentType 
    = WebConfigurationManager.AppSettings["Anthem.ResponseType"];
    #else
        contentEncoding 
    = ConfigurationSettings.AppSettings["Anthem.ResponseEncoding"];
        contentType 
    = ConfigurationSettings.AppSettings["Anthem.ResponseType"];
    #endif
        
    if (contentEncoding != null)
            resp.ContentEncoding 
    = Encoding.GetEncoding(contentEncoding);
        
    if (contentType != null)
            resp.ContentType 
    = contentType;
        resp.Cache.SetCacheability(HttpCacheability.NoCache);
    }


    小结一下使用 Anthem.NET 碰到脚本问题的查错方法:
    首先定位到 Anthem.NET 产生的某个具体函数,然后,可以在页面的 </body> 前插入代码来改写该函数,在其中加入调试语句来定位问题。

    当然,以上所说的是在部署服务器这种受限的环境下(通常没有开发环境)排错的方法,如果能够直接调试页面的 JavaScript 就更方便了。比如可以用 Visual Studio, 或者 MSE.exe 等工具来调试。
  • 相关阅读:
    SSL 1579——泽泽在巴西
    SSL 1644——取数字问题
    SSL 1589——火车票
    SSL 1506——打鼹鼠
    SSL 1212——大厅安排
    洛谷 1064——金明的预算方案(动态规划的背包问题)
    SSL 1463——公共子串
    SSL 1461——最大连续数列的和
    SSL 1643——最小乘车费用
    SSL 1460——最小代价问题
  • 原文地址:https://www.cnblogs.com/RChen/p/anthem_debug1.html
Copyright © 2020-2023  润新知