文/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 测试通过。
下载测试代码| 感谢原创者的辛勤劳动,希望对您有所帮助,转载请注明原出处。 |