ASP.NET AJAX 中的 Response.Write 错误

文/kuiyouli  出处/博客园

        真是有点落伍了,最近才开始研究Ajax 。
   
        前不久看了几个Ajax项目,感觉真是爽得没话说呀,忍不住也想把自己的项目“整顿”一下,弄了个测试页面,拖了几个 UpdatePanel 进去。我拷,果然神奇,是那么的简单,不搞任何代码就实现无刷新,忙喝杯开水庆祝一下。

        一激动就把项目几个母版都改了下,调试运行,这话真是说不出口呀,原本漂亮的页面被搞得面目全非呀,那个JS错误是一个接一下,犹如晴空霹雳,耳朵都振得发麻,按得手都发软。哎,我这善良的人民呀,为何招如此劫数。。。。
 附件: 您所在的用户组无法下载或查看附件

        没办法咯,我又不像是那种爱走回头路的人,于是Google, baudu狂搜,终于找出了真凶,Resposne.Write  ,自定义控件中的 CSS,JS,好说,问题找到了,何愁大事不成。
 附件: 您所在的用户组无法下载或查看附件

        还好VS2008对Javascript的调试还算见得人,方便。F11,F10,把Ajax的Javascript Copy出来分析下,呵呵,原来问题出在XMLRequest返回值的解析中,不难解决,只是搞不懂,微软AJAX团队这样处理肯定有他的道理 ,他们是咋样的呢?搞不懂,实在搞不懂。。。。

        前面都是废话,说一下我的解决方法,我先抛块砖,兄弟们有玉的就扔过来。

        UpdatePanel在回传后,都是通过客户端Sys.Net.XMLHttpExecutor实例的get_responseData方法来获取返回的HTML,然后解析,之后经过一些“乱七八糟”的处理后会调用Sys.WebForms.PageRequestManager实例的_endPostBack函数,呵呵,我何不在这get_responseData、_endPostBack上下功夫。惯用的手法,偷梁换柱,
 附件: 您所在的用户组无法下载或查看附件写个函数将get_responseData、_endPostBack替换,JS代码如下



1
2window.attachEvent("onload",function()
3{
4    if(window.oc_webcontrols_aspnetAjaxScriptLoaded!=true && window.Sys && window.Sys.WebForms && window.Sys.WebForms.PageRequestManager)
5    {
6        window.oc_webcontrols_aspnetAjaxScriptLoaded=true;
7        var old_endPostBack=Sys.WebForms.PageRequestManager._instance._endPostBack
8        Sys.WebForms.PageRequestManager._instance._endPostBack=function(error,response)
9        {
10            if(response && response._xmlHttpRequest)
11            {
12                var responseText=response._responseText
13                old_endPostBack.apply(this,arguments);
14                Handle(responseText);
15                window.setTimeout("document.body.fireEvent('onload');",50);
16            }
17        }
18
19        function Handle(responseText,insertToBody)
20        {
21            var div=document.createElement("Div");
22            div.innerHTML=" "+responseText;
23           
24            var links=div.getElementsByTagName("link");
25            for(var i=0;i<links.length;i++)
26            {
27                var style=document.createStyleSheet(links.href);
28                links.outerHTML="";
29            }
30           
31            var styles=div.getElementsByTagName("style");
32            for(var i=0;i<styles.length;i++)
33            {
34                var style=document.createStyleSheet();
35                style.cssText=styles.innerHTML;
36                styles.outerHTML="";
37            }
38           
39            var scripts=div.getElementsByTagName("script");
40            for(var i=0;i<scripts.length;i++)
41            {
42                var script=scripts;
43                try
44                {
45                    if(script.src!="" && script.src!=null)
46                    {
47                        var scriptElement=document.createElement("script");
48                        scriptElement.src=script.src;
49                        scriptElement.language=script.language
50                        scriptElement.type=script.type;
51                        document.body.appendChild(scriptElement);
52                    }
53                    else
54                    {
55                        eval(script.innerHTML);
56                    }
57                }
58                catch(e)
59                {
60                    alert("脚本注册失败:\n"+e.message+"\n\n"+script.outerHTML);
61                }
62                script.outerHTML="";
63            }
64           
65            if(insertToBody)
66            {
67                document.body.insertAdjacentHTML("afterBegin",div.innerHTML.substring(6));               
68            }
69        }
70                           
71        var get_responseData=Sys.Net.XMLHttpExecutor.prototype.get_responseData
72        Sys.Net.XMLHttpExecutor.prototype.get_responseData=function()
73        {
74            if(this._responseText==null)
75            {
76                this._responseText=get_responseData.call(this);
77                var index=this._responseText.match(/\d{1,4}\|updatePanel\|/i).index;
78                if(index>0)
79                {
80                    this.resposneWriteText=this._responseText.substring(0,index);
81                    this._responseText=this._responseText.substring(index);
82                    Handle(this.resposneWriteText,true);
83                }
84            }
85            return this._responseText;
86        }
87    }
88   
89})

        以上方法只对IE有用 ,FF下要稍作修改,仅用 UpdatePanel 测试通过。

        下载测试代码

 感谢原创者的辛勤劳动,希望对您有所帮助,转载请注明原出处。
 您可能对 [Ajax] 的这些文章也感兴趣:

ASP.NET的AJAX控件工具包已经更新
Ajax中文乱码问题解决办法
AJAX编程实践之与服务器通信
AJAX初体验之上手篇
如何使用ajax开发web应用程序[3]
ajax开发工具bindows使用指南:标记
冷静对待互联网流行技术风潮:忽悠一下Ajax
如何学习AJAX
在 AJAX 开发中集成数据库技术
Google Ajaxslt 使用