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 等工具來調試。

 

出處:http://www.cnblogs.com/RChen/archive/2006/12/16/anthem_debug1.htmljavascript

相關文章
相關標籤/搜索