客户端回调

Client Callback 是ASP.NET 2.0新增的一个特性。简单的说,就是在不刷新页面的情况下,用javascript向服务器端传递参数、调用服务器端的方法、并且得到服务器端的返回值进行处理。

 

1>   Why Client Callback

 

HTTP是无状态的协议。在HTTP协议之上开发的项目,常常需要从客户端调用服务器端的方法、执行服务器端的代码、从服务器端获取数据。这些都首先需要提交当前的页面,并且产生一次Postback过程。每次Postback都会让客户端的浏览器重新Render当前的页面。

 

这样的事件模型下,开发员不得不小心地维护客户端各控件的当前状态以保证它们不会丢失、不得不小心地维护ViewState的状态以避免出现不一致的情况。同时,庞大的ViewState也会造成页面的冗杂、下载速度变慢。另一方面,重新Render页面当然会耗费浏览器的时间来处理。如果页面很“重”——比如有很多的DHTML或者很多的控件——这当然会增加客户的等待时间,而频繁的等待常常会让客户不耐烦。最后,页面的频繁刷新恐怕会把所有人的眼睛弄花。

 

因此,从客户端代码(javascript)里调用服务器端的方法,以避免页面重新Rener和频繁刷新就是很有必要了。

 

2>   XMLHTTP

 

在ASP.NET 2.0之前,我们实现这一功能的方式主要是XMLHTTP。Client Callback的底层实现机制也是XMLHTTP。XMLHTTP是在客户端详服务器端发送请求并且得到服务器端返回值的一种古老而经典的技术,比如下面这个例子。

None.gif<script language="javascript">
None.gif    functiongetXmlHttp ( )
None.gif    {
None.gif        varXmlHttp = newActiveXObject("Msxml2.XMLHTTP.4.0");
None.gif        XmlHttp.Open("GET", "http://www.yahoo.com", false);
None.gif        XmlHttp.Send();
None.gif        varhomesource =XmlHttp.responseText ; 
None.gif        document.all.aa.innerHTML =homesource ;
None.gif    }
None.gif</script>
None.gif<body id="bodyTag">
None.gif    <input type="button"name="btnyahoo"value="click 4 yahoo"onclick="getXmlHttp();">
None.gif    <div id="aa"name="aa"></div>
None.gif</body>
None.gif

当点击button时,触发的javascript函数会创建一个HTTP的请求,并发送给指定的URL。接收到服务器端的响应之后,把收到的信息展现出来,我们就可以在自己的网页中看到yahoo的页面了。

 

这一句XmlHttp.Open("GET", "http://www.yahoo.com", false);的第一个参数标识HTTP请求的方式是“GET”或者“POST”。第二个参数是请求发送目的的指定URL,可以在URL中包括以“?”标识以“&”连接的查询字符串。第三个参数是标识页面的请求与页面的响应是否同步,即是否应该等待服务器端的响应之后再进行页面的下一步响应。此处设为false,既不等待服务器端的响应,以异步方式处理。

 

接下来的一句XmlHttp.Send();是发送刚刚生成的HTTP请求。我们可以将要传给服务器端的参数填入Send函数的参数里,在服务器端进行解析。

 

       接受的信息不仅仅是ResponseText的信息。如果把XmlHttp.responseText 改成XmlHttp.GetAllResponseHeaders;我们就可以看到服务器发回的所有HTTP头信息了:)

[
注意:增加XMLHttpRequest读取中文网页时返回乱码的解决办法

XMLHttpRequest 默认是用UTF-8 传递数据。当服务端的返回数据是UTF-8编码的时候,它工作得很好(开发web应用,当服务端和客户端以及数据库统一使用UTF-8编码可以有效的避免乱码问题)。如果服务端设置了正确的Content-Type Response Header以及编码信息,那么XmlHttpRequest也可以正确工作。 
可是当使用XMLHttpRequest读取中文网页内容时, 如果服务端的程序没有设置Content-Type Response Header,或者Header没有设置编码类型,那么我们访问responseText属性的时候就可能遭遇乱码。如以下代码用XMLHttpRequest获取雅虎中国网站的星座站首页:  

xmlhttp = getXMLHttpRequest(); 
var url = "
http://cn.astrology.yahoo.com/";; 
xmlhttp.open("GET", url, true); 
xmlhttp.onreadystatechange = function(){ 
if (xmlhttp.readyState == 4) 
    if (xmlhttp.status == 200) 
        alert(xmlhttp.responseText); 
}; 
xmlhttp.send(null); 
纵使yahoo中国这样专业的网站,对web标准的支持还很不彻底,弹出的html源码中充斥不符合web标准的html标签,当然还有已预见的乱码。 

同样遗憾的是,FireFox 和 IE 的解决方法也是南辕北辙 

FireFox 


FireFox 的XMLHttpRequest对象支持overrideMimeType方法,可以指定返回数据的编码类型,利用该方法可以解决中文乱码,前面的代码修改如下:  

xmlhttp = getXMLHttpRequest(); 
var url = "
http://cn.astrology.yahoo.com/";; 
xmlhttp.open("GET", url, true); 
xmlhttp.overrideMimeType("text/html;charset=gb2312");//设定以gb2312编码识别数据 
xmlhttp.onreadystatechange = function(){ 
if (xmlhttp.readyState == 4) 
    if (xmlhttp.status == 200) 
        alert(xmlhttp.responseText); 
}; 
xmlhttp.send(null); 
Internet Explorer 


IE不支持overrideMimeType方法,并且只能用一种很蹩脚的方法来解决,此时需要引入一个杂交的函数:  

function gb2utf8(data){ 
    var glbEncode = []; 
    gb2utf8_data = data; 
    execScript("gb2utf8_data = MidB(gb2utf8_data, 1)", "VBScript"); 
    var t=escape(gb2utf8_data).replace(/%u/g,"").replace(/(.{2})(.{2})/g,"%$2%$1").replace(/%([A-Z].)%(.{2})/g,"@$1$2"); 
    t=t.split("@"); 
    var i=0,j=t.length,k; 
    while(++i<j) { 
        k=t[i].substring(0,4); 
        if(!glbEncode[k]) { 
            gb2utf8_char = eval("0x"+k); 
            execScript("gb2utf8_char = Chr(gb2utf8_char)", "VBScript"); 
            glbEncode[k]=escape(gb2utf8_char).substring(1,6); 
        } 
        t[i]=glbEncode[k]+t[i].substring(4); 
    } 
    gb2utf8_data = gb2utf8_char = null; 
    return unescape(t.join("%")); 
}xmlhttp = getXMLHttpRequest(); 
var url = "
http://cn.astrology.yahoo.com/";; 
xmlhttp.open("GET", url, true); 
xmlhttp.onreadystatechange = function(){ 
if (xmlhttp.readyState == 4) 
    if (xmlhttp.status == 200) 
        alert(gb2utf8(xmlhttp.responseBody)); //注意这里要用responseBody 
}; 
xmlhttp.send(null); 
gb2utf8函数直接解析XMLHttpRequest返回的二进制数据,其中要利用execScript方法来执行VBScript的函数。所以说是一个杂交的函数。感谢blueidea论坛 提供的算法。 

虽然有了解决的办法,但形式丑陋,而且不符合web标准。所以应该在编程中尽量避免,如果是开发web应用,应尽量使用UTF-8编码,或者在服务端设置正确的编码信息。至于以上范例,有盗取其他网站内容的嫌疑,更是不为提倡。  


gb2utf8函数确实好用!

3>   Client Callback in ASP.NET 2.0

 

ASP.NET 2.0中新增了ICallbackEventHandler接口和Page.GetCallbackEventHandler方法来实现Client Callback的调用。

 

ICallbackEventHandler接口只有一个方法需要实现:string RaiseCallbackEvent(string eventArgument);这个方法就是在服务器端处理客户端调用请求的方法。参数eventArgument是从客户端传递的参数,返回值则是需要返回给客户端的处理结果。

 

Page.GetCallbackEventHandler方法共有三个重载方法,但都大同小异。这个方法的作用是生成一段在初始化Callback时供客户端调用的javascript代码段。以下面这种重载实现为例:

None.gif[System.ComponentModel.EditorBrowsableAttribute(2)]
None.gifpublic string GetCallbackEventReference(System.Web.UI.Control control, string argument, string clientCallback, string context, string
 clientErrorCallback);
None.gif

第一个参数是实现了ICallbackEventHandler接口的控件,.Net Framework将在内部调用该控件实现的RaiseCallbackEvent的方法。一般该参数为Page本身。第二个参数是从客户端代码中需要传递到服务器段的参数的变量名。第三个参数是处理服务器端返回给客户端处理结果后,客户端处理返回值的函数名。第四个参数是context变量的变量名。最后一个参数是,在回调过程中如果在服务器端发生异常,在客户端接受异常信息并处理该信息的函数名。

 

对于客户端的实现,需要在客户端代码中定义传参的变量,定义context变量,并且以<%...%>的方式访问服务器端变量,以调用服务器段的Page.GetCallbackEventHandler()方法。当调用Page.GetCallbackEventHandler方法时,客户端代码中的<%...%>部分会被替换成对__doCallback()客户端函数的调用。__doCallback函数是.Net Framework 2.0内置的一个javascript函数,作用是产生一段通过XMLHTTP方式对服务器端代码的调用。__doCallback函数的参数是同服务器端的GetCallbackEventHandler被调用时的参数完全一致。

 

客户端的context变量是一个很有趣的东西。在整个回调过程中,context变量都被浏览器缓存起来,而且不被发送到服务器端。context变量是由开发员设计的,它的作用是在多次回调间对不同的回调起标识作用。在客户端的处理服务器处理结果返回值的函数里,只需要判断context变量的自定义属性,就可以得到关于回调的标识信息。

 

客户端的实现包括:若干个初始化回调的函数、一个处理回调返回值的函数、和一个处理回调异常的函数。第二个函数的两个参数分别是服务器端返回值的字符串和context变量。第三个函数的参数分别是服务器端的异常信息和context变量。

        Client Callback的调用顺序,首先通过调用GetCallbackEventHandler将客户端代码里的<%...%>表达式转化为__doCallback函数的调用。第二步,初始化回调时,通过__doCallback将要传递的参数发送给服务器端的RaiseCallbackEvent方法。第三步,回调结束,RaiseCallbackEvent的返回值传到客户端代码的对应函数处理。如果回调有异常,则通过客户端的错误处理函数处理。

 

4>   Client Callback小结

 

不是所有的浏览器都支持Client Callback,因此可能需要使用.Net Framework 2.0新增的两个属性:SupportsCallback和SupportsXmlHttp。这两个属性都在Request.Browser下面。现在当然所有的浏览器对这两个属性的返回值都是一样的,或者全true,或者全false。之所以要设这两个属性,是为了将来的扩展。也许,以后的Client Callback不是用XmlHttp实现的呢:)

 

Client Callback通过XmlHttp,其实是对服务器的另一个同名页面的请求和处理。因此,使用Client Callback的时候要很小心。首先不要在服务器端代码里试图取控件的值,因为这是在另一个页面里处理,此时取得的不是当前页面的当前值。也就是说,不要使用从客户端传递的参数以外的任何值。其次,由于整个回调过程都没有将当前的表单提交,因此,要小心的维护页面的ViewState或者Session值。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/467309.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

初步使用计算机说课,初步认识计算机说课稿

探索、自主发现式学习。根据教材特点与学生实际&#xff0c;我制订以下三维学习目标&#xff1a;1、了解计算机的历史和发展趋势。2、认识计算机的系统组成。3、激发学生学习计算机硬件知识的兴趣。4、提高学生学习、使用计算机的兴趣和互相合作意识品质。三、教学环境&#xf…

万事开头难 - 介绍IMX6ULL启动方式

不同开发板&#xff0c;启动方式不一样&#xff0c;今天我们来介绍imx6ull开发板的启动方式&#xff0c;这非常重要。若不了解清楚启动方式&#xff0c;后面的所有开发工作便无从谈起。本文摘自100ask_imx6ull 开发板 配套学习手册-《嵌入式Linux应用开发完全手册_韦东山全系列…

软件架构培训

在沈阳参加了软件架构培训&#xff0c;感觉非常好&#xff0c;老师讲的很适合我们的应用。真是受益非浅啊&#xff0c;把具体培训内容贴上&#xff1a; 课程名称&#xff1a;OOSE培训 课程目标&#xff1a; • 从广义角度理解软件框架的形成过程&#xff08;RUP的过程裁剪&…

SVN cleanup 反复失败解决办法

svn cleanup cleaning up 操作反复失败&#xff0c;svn提示的问题是版本需要更新&#xff0c;更新成最新的版本之后&#xff0c;依旧反复失败&#xff0c;陷入死循环。还好找一个blog上的方法试了一下&#xff0c;成功了。先说故障环境&#xff1a;OS: win7 x64TortoiseSVN 1.9…

可以在中断服务程序执行malloc吗?

这是微信群里面的一个群友提的问题&#xff0c;原问题如下&#xff1a;今天遇到一个面试问题 请教各位老哥 中断服务程序能否malloc &#xff1f;为什么&#xff1f;我回答是 不行 因为中断服务程序应该要尽量简短&#xff0c;且执行完中断服务程序会跳出中断函数&#xff0c…

my eclipse 类似dreamweaver编辑html,8款替代Dreamweaver的开源网页开发工具

Adobe Dreamweaver虽然非常好用&#xff0c;但它并不是唯一一个能够设计、开发、发布精彩网站的Web开发集成环境。我们的开源世界里有很多非常棒的可以完全替代Dreamweaver的各种功能的优秀Web开发工具&#xff0c;更重要的&#xff0c;是免费的。如果你正在寻找Dreamweaver的替…

Android Input 子系统初探

Android系统基于Linux内核实现&#xff0c;内核作为整个操作系统的核心&#xff0c;对下&#xff0c;它负责整个硬件的驱动、实现对硬件器件的控制管理&#xff1b;对上&#xff0c;它提供各种系统所需的核心功能。Android系统支持的输入设备较多&#xff0c;如按键、触摸屏、手…

Ruby零碎笔记

Ruby零碎笔记 飞机上阅读pdf的笔记&#xff0c;因为不联网&#xff0c;内容不多而且比较零散&#xff0c;以tips的形式记录 tips 查看当前作用域的变量puts local_variables ruby中方法传递参数时&#xff0c;括号是可选的脚本开始运行时&#xff0c;main对象会被自动创建&…

网管日志-06.07.25

昨天晚上回家的时候已经是23:30左右了&#xff0c;尽管电信的工程师已经测试出了光信号衰减状况&#xff0c;也进行了相应的处理&#xff0c;最后达到了单芯光纤-11db的“理想”状态&#xff0c;可能用户也对这个值非常满意&#xff0c;我们也折腾到了大半夜。我是在地下网络机…

html5控制符置于底层,HTML5占位符在焦点上消失

Stefano J. Attardi写了一个不错的jQuery插件&#xff0c;只是这样。它比罗伯特的更稳定&#xff0c;并且当场得到焦点时&#xff0c;还会变淡到更浅的灰色。我修改他的插件读取占位符属性&#xff0c;而不是手动创建跨度。This fiddle具有完整代码&#xff1a;HTMLJS// Origin…

spring AspectJ的Execution表达式

Aspectj切入点语法定义 在使用spring框架配置AOP的时候&#xff0c;不管是通过XML配置文件还是注解的方式都需要定义pointcut"切入点" 例如定义切入点表达式 execution(* com.sample.service.impl..*.*(..)) execution()是最常用的切点函数&#xff0c;其语法如下所示…

计算机excl知识题,2019职称计算机考试Excel模拟题及答案(1.18)

【导语】2019年职称计算机考试备考正在进行中&#xff0c;为了方便考生及时有效的备考&#xff0c;那么&#xff0c;无忧考网为您精心整理了2019职称计算机考试Excel模拟题及答案(1.18)&#xff0c;把握机会抓紧练习吧。如想获取更多职称计算机考试的模拟题及备考资料&#xff…

CPU中的程序是怎么运行起来的

总述最近一位朋友问我&#xff0c;开发的代码是怎么在芯片运行起来的&#xff0c;我就开始给他介绍代码的预编译、汇编、编译、链接然后到一般的文件属性&#xff0c;再到代码运行。但是大佬问了我一句&#xff0c;CPU到底是怎么执行到每一个逻辑的&#xff0c;就讲了哈CPU的架…

MspEmu W.I.P.

转载于:https://www.cnblogs.com/sesexxoo/archive/2006/07/29/6190717.html

Git-远程操作

远程分支&#xff1a;远程跟踪分支remote branch是对远程分支状态的引用&#xff0c;是不能移动的&#xff0c;它会根据远程分支变化以及网络通信自动移动。Git服务器包含了远程分支master&#xff0c;在My Computer中的remote branch就是远程跟踪分支&#xff0c;是对git服务器…

计算机语言学 自然语言处理程序,利用知网进行(计算机)自然语言处理

摘要&#xff1a;自然语言理解,特别是中文信息处理,一直是计算机界的难题.让计算机来理解和处理丰富的自然语言,极具挑战性.自然语言的计算机处理是一个多学科交叉研究领域.来自计算机科学,语言学,数学等不同学科的研究人员构成了目前这一领域的主要研究力量.自然语言处理就是研…

对于鸿蒙的一点见解

周五我在东莞出差&#xff0c;下班后看了开发者大会的视频回放&#xff0c;回到酒店&#xff0c;我跟邓总说&#xff0c;我们今天不要拍视频&#xff0c;也不要打王者了&#xff0c;你给我下鸿蒙的代码来看看&#xff0c;然后&#xff0c;那天晚上我们都没有上线王者&#xff0…

今天雨很大

早上就开始下雨了,一直到现在. 来公司发现翻译来了,一个星期前面试过的那个. 不知道做什么了,看来只能开始英文的B2B了.一直忙来忙去,突然早一天完成了工作,余下的一天不知道做什么. 昨天晚上在家里的机子练习时,多学会了一些东西,看来有必要多看一些别人的例子,…

Linux内存管理slub分配器

背景Kernel版本&#xff1a;4.14ARM64处理器&#xff0c;Contex-A53&#xff0c;双核使用工具&#xff1a;Source Insight 3.5&#xff0c; Visio1. 概述之前的文章分析的都是基于页面的内存分配&#xff0c;而小块内存的分配和管理是通过块分配器来实现的。目前内核中&#xf…

大学计算机科学不会编码,华中科技大学人员编号编码管理办法

第一条 为进一步推进学校管理的信息化、规范化和系统化&#xff0c;加强对我校教职工、学生等各类人员基本信息的统一管理&#xff0c;结合学校实际情况&#xff0c;制定本管理办法。第二条 凡在我校工作、学习的教职工、学生、短期聘用人员及其他人员&#xff0c;均拥有由10…