linux社区爱心援助Linux认证系列教程业界动态站务新闻公司招聘建议留言网址大全LPI专题CISCO专题
设为首页
加入收藏
管理团队
JSP  
JAVA  
PERL  
 您的位置:首页 > 开发语言 > asp.net >
栏目导栏
  php
  JSP
  ASP
  asp.net
  JAVA
  c/c++/c#
  perl
  JavaScript
  Basic
  Delphi
资料搜索
热门文章
·NetBPM工作流的一个示例:请假
·asp.net正则表达式语法
·Office Web Components(OWC)绘
·数据源为空时如何让GridView显
·asp.net ajax客户端编程+jquer
·如何让UpdatePanel支持文件上传
·Ado.Net读取Excel常见问题总结
·asp.net 2.0 ajax中使用PopupC
·Brettle.Web.NeatUpload.dll支
·C#.Net的常见面试试题和参考答
·如何使IE的后退按钮无效
·ASP.NET DEMO 15: 同时支持行单
·ASP.NET 2.0 异步页面原理浅析
·url重写实现任意二级域名或多级
·asp.net:正确判断当前用户角色
最新文章
·Ajax Control Toolkit Animati
·讨论一下类似BlogEngine内一次
·使用CSS+SiteMap+UserControl+
·Asp.net中多彩下拉框的实现
·浅谈ASP.NET的Postback
·分清ASP.NET AJAX中的Extender
·Tip:在使用AjaxControlTookit
·有关注册DataItem的一些可能被
·IIRF(Ionic's Isapi Rewrite
·asp.net 客户端回调功能的实现
·关于控件部分的看法--读Progra
·为什么在vista上做开发
·如何封装JS和CSS文件为服务器端
·岂今我看过的最强的排序算法
·设计模式学习笔记之单件模式
Google
 
asp.net 客户端回调功能的实现机制探讨(响应部分及可能的优化)
[ 作者:  加入时间:2007-12-28 12:17:24  来自:Linux联盟收集整理 ]
上一部分说道在发送前,已经将回调函数赋值成
  xmlRequest.onreadystatechange = WebForm_CallbackComplete;
  那么咱们就先来看看这个callback方法。
  function WebForm_CallbackComplete() {
   for (i = 0; i < __pendingCallbacks.length; i++) {
   callbackObject = __pendingCallbacks[i];
   if (callbackObject && callbackObject.xmlRequest && (callbackObject.xmlRequest.readyState == 4)) {
   WebForm_ExecuteCallback(callbackObject);
   if (!__pendingCallbacks[i].async) {
   __synchronousCallBackIndex = -1;
   }
   __pendingCallbacks[i] = null;
   var callbackFrameID = "__CALLBACKFRAME" + i;
   var xmlRequestFrame = document.getElementById(callbackFrameID);
   if (xmlRequestFrame) {
   xmlRequestFrame.parentNode.removeChild(xmlRequestFrame);
   }
   }
   }
  }
  这是获得一个挂起的未处理回调队列,并且如果队列里面的是以xmlrequest发送的ajax的请求,而且状态为4的话,那么调用方法:WebForm_ExecuteCallback方法。
  当然如果是通过iframe来发送ajax请求的话,那么就是将先前的iframe移除掉。
  下一部分就是WebForm_ExecuteCallback方法:
  function WebForm_ExecuteCallback(callbackObject) {
   var response = callbackObject.xmlRequest.responseText;
   if (response.charAt(0) == "s") {
   if ((typeof(callbackObject.eventCallback) != "undefined") && (callbackObject.eventCallback != null)) {
   callbackObject.eventCallback(response.substring(1), callbackObject.context);
   }
   }
   else if (response.charAt(0) == "e") {
   if ((typeof(callbackObject.errorCallback) != "undefined") && (callbackObject.errorCallback != null)) {
   callbackObject.errorCallback(response.substring(1), callbackObject.context);
   }
   }
   else {
   var separatorIndex = response.indexOf("|");
   if (separatorIndex != -1) {
   var validationFieldLength = parseInt(response.substring(0, separatorIndex));
   if (!isNaN(validationFieldLength)) {
   var validationField = response.substring(separatorIndex + 1, separatorIndex + validationFieldLength + 1);
   if (validationField != "") {
   var validationFieldElement = theForm["__EVENTVALIDATION"];
   if (!validationFieldElement) {
   validationFieldElement = document.createElement("INPUT");
   validationFieldElement.type = "hidden";
   validationFieldElement.name = "__EVENTVALIDATION";
   theForm.appendChild(validationFieldElement);
   }
   validationFieldElement.value = validationField;
   }
   if ((typeof(callbackObject.eventCallback) != "undefined") && (callbackObject.eventCallback != null)) {
   callbackObject.eventCallback(response.substring(separatorIndex + validationFieldLength + 1), callbackObject.context);
   }
   }
   }
   }
  }
  
  这部分就是返回的值如果是以e开头的话调用异常方法,证明服务器端出错,如果以's'开头或者存在'|'字符的话,那么就调用回调成功的方法,如果以'e'开头的话那么就调用错误处理方法,如果你注册了的话。
  
  在实际的测试中,我改变几种策略来揣摩它的机制:
  服务器端直接抛出异常:结果用抓包工具观察到果然是返回'e'。
  public String GetCallbackResult() 方法直接response.write一个字符串,但是却不返回数据,并catch住当前模块,目的是想直接输出某些东西,并且绕过它自有的实现机制,比如自由控制异常与否,自由控制异常,但是结果抓包显示:e正在中止线程。也就是说response.write使得当前线程终止了,这个异常被它捕获到并且返回给了客户端。
  另外一个变通:将服务器重定向。
  public String GetCallbackResult()
   {
  
   try
   {
   Response.Redirect("http://www.163.com");
   // Response.Write("asd");
   Response.End();
  
   }
   catch { }
   finally
   {
  
   } return "";
   }
  这样的话,跟踪到的结果确是 0| 也就是说看起来正常。前一种测试它能捕获到异常,说明客户端回调的回调结果处理应该在response.end之后,那么应该就是在endrequest 这个阶段做的回调结果返回的处理。(没有记错的话beginrequest是模块里面最后一个了。)而redirect方法(304重定向)却不会触发这个事件,所以服务器端没有捕获到而只是返回了结果。
  
  
  好了,整个已经研究完了,我想来说点感想,首先是这个做得是比较完美,如果不支持xmlrequest对象,还采用了iframe的形式来进行支持,不过多写了好多代码.......另外是否能将其优化为在服务器端智能判断客户端的浏览器类型,然后输出js文件呢?不支持xmlrequest对象的浏览器应该能从客户端发送过来的客户端环境变量中检索出来,并且让各客户端各取所需,那样不是很好吗?这样就不会造成在ie和ff浏览器99% 份额的时候为了1%而不必要做了如下的冗余措施:
  在浏览器尚未加载完的时候调用WebForm_InitCallback将页面所有的控件和值作为键值对存储起来,并将其encode。这个操作显得非常多余。而且浪费时间和资源。
  同时也看到了asp.net发送了很多与之无关的代码都发送了过来,比如只有在MaintainScrollPositionOnPostback为 true的时候才需要的代码,以及页面上有Defaultbutton的时候才有的代码等等,都一股脑全部过来了。实在是有些浪费资源。另外看到 asp.net的js脚本代码写的也不是很省,比如这段:
  var callback = new Object();
   callback.eventCallback = eventCallback;
   callback.context = context;
   callback.errorCallback = errorCallback;
   callback.async = useAsync;
  
  可以改成:
  var callback = {eventCallback:eventCallback,context:context,errorCallback:errorCallback,async:useAsync}
  这在prototype框架中经常见到,这样写避免了使用with语句来消耗资源,也减少了很多代码,节省了字节数。
  
  所以asp.net在快速开发这一块的确是非常好,但是也封装了不少东西,在企业级的应用当中,要想获得更好的性能还是只有自己手写不少代码,来弥补性能,当然,asp.net也留下了不少可扩展的空间,只要你熟悉它的机制。
Linux联盟收集整理 ,转贴请标明原始链接,如有任何疑问欢迎来本站Linux论坛讨论
评论】【加入收藏夹】【 】【打印】【关闭
※ 相关链接
 ·关于控件部分的看法--读Programming ASP.NET中文版  (2007-12-28 12:14:20)
 ·如何封装JS和CSS文件为服务器端控件---ASP.NET 2.0  (2007-12-28 12:12:19)
 ·Asp.net Ajax:我可以用javascript做些什么  (2007-12-13 15:51:42)
 ·asp.net ajax客户端编程+jquery:实现泛型数据的客户端数据调用、添加、删除  (2007-12-13 15:50:59)
 ·客户端回调实现gridView无刷新分页  (2007-12-13 15:42:27)
 ·ASP.NET验证控件详解  (2007-12-03 15:34:17)
 ·数独解算器(ASP.NET 2.0)  (2007-11-30 13:34:41)
 ·客户端回调实现gridView无刷新分页  (2007-11-30 13:31:04)
 ·ASP.NET动态创建控件之绝境求生  (2007-11-30 13:30:25)
 ·ASP.NET如何进行性能优化问题  (2007-11-30 13:29:43)