客户端回调

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,一经查实,立即删除!

相关文章

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

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

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

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

Android Input 子系统初探

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

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

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

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

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

Git-远程操作

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

对于鸿蒙的一点见解

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

Linux内存管理slub分配器

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

逆向知识第十讲,循环在汇编中的表现形式,以及代码还原

逆向知识第十讲,循环在汇编中的表现形式,以及代码还原 一丶do While在汇编中的表现形式 1.1高级代码: #include "stdafx.h"int main(int argc, char* argv[]) {int nSum 0;int i 0;do {nSum nSum i;} while (i <100);return 0; } 高级代码很简单,只是一个简单…

做技术知道了哪些事情代表自己成熟了?

如果技术圈是一个江湖&#xff0c;每个人初入江湖的时候都懵懵懂懂的&#xff0c;从懵懂到老练&#xff0c;从老练到老油条&#xff0c;这个是一个过程&#xff0c;过程中总是有一些比较有用的观点&#xff0c;这些观点&#xff0c;就表示你从小白上升到老白的过渡。这些观点&a…

数据结构复习笔记(2)

1&#xff0c; 若入栈的元素为n,则可得到的输出序列数量为 (2n)!/(n1)(n!)(n!)。2&#xff0c; 用两个长度相同的栈S1,S2构造一个队列。在S1中进行入队操作&#xff0c;S2中进行出队操作 &#xff0c;判断队列空的条件是&#xff0c;S1和S2同时为空&#xff0c;判断队列满的条…

用于MCU,基于FreeRTOS的micro(轻量级)ROS

编辑整理&#xff1a;strongerHuang作者&#xff1a;Francesca Finocchiaro关注我的读者中应该有部分是做ROS相关的工作&#xff0c;今天就来分享一个基于FreeRTOS的micro&#xff08;微型&#xff09;ROS。一、关于ROSROS&#xff1a;Robot Operating System,&#xff0c;即机…

【干货】同步与互斥的失败例子

韦东山老师最新录制的驱动大全之<<同步与互斥>>收费视频已经在淘宝上架销售 &#xff0c;一共7节&#xff0c;良心价29元&#xff0c;同时已经同步到CSDN , 51CTO , 电子发烧友&#xff0c;腾讯课堂等平台。本文是其中一节《同步与互斥的失败例子》视频配套文档&am…

TCP三次握手

以下是我做的实验 &#xff0c;180.97.33.108 是百度 以下是我自己画的图 转载于:https://www.cnblogs.com/heben/p/7879439.html

Linux中断子系统-通用框架处理

背景Kernel版本&#xff1a;4.14ARM64处理器&#xff0c;Contex-A53&#xff0c;双核使用工具&#xff1a;Source Insight 3.5&#xff0c; Visio1. 概述《Linux中断子系统&#xff08;一&#xff09;-中断控制器及驱动分析》讲到了底层硬件GIC驱动&#xff0c;以及Arch-Specif…

接口测试工具-fiddler的运用

本篇主要介绍一下fiddler的基本运用&#xff0c;包括查看接口请求方式&#xff0c;状态响应码&#xff0c;如何进行接口测试等 一&#xff0e;Fiddler的优点 独立的可以直接抓http请求小巧、功能完善快捷、启动就行代理方便二&#xff0e;什么是Fiddler Fiddler是一个http协议调…

微电子科学与工程要学计算机吗,微电子科学与工程专业就业前景如何 有前途吗...

微电子科学与工程专业就业前景如何&#xff1f;有前途吗&#xff1f;下面小编为大家整理了相关内容&#xff0c;以供参考&#xff0c;一起来看看吧&#xff01;微电子科学与工程专业就业前景微电子科学与工程专业近年来也逐渐热火起来了&#xff0c;竞争力也很大。微电子专业一…

我的丈母娘

2020年9月17日12点46分&#xff0c;刚进入新居我终于还是要写这篇文章了&#xff0c;想了很久&#xff0c;我觉得写一篇文章来记录下我的丈母娘。前段时间&#xff0c;小云妈妈骑车不小心把鼻子给摔破了&#xff0c;很严重&#xff0c;二哥马上回家带老人到医院检查并做了手术。…

OpenGL程序运行提示“glut32.dll丢失问题”

调试环境&#xff1a; Win10 (x64) &#xff0c;VS2015 解决方案 &#xff08;1&#xff09;将gult32.dll&#xff0c;glut.dll复制到C:\WINDOWS\SysWOW64 (如果是32位操作系统&#xff0c;则是WINDOWS\system32这个文件下) &#xff08;2&#xff09;将GL文件夹的路径添加到vs…

华为突然宣布,对物联网下手了!

5G时代到来物联网技术的应用离我们越来越近智慧交通、智能家庭、智慧园区越来越多的融入到我们的生活当中但国内物联网人才短缺每年人才缺口达百万之多作为5G技术的先锋华为云特别推出【IoT物联网开发全栈成长计划】三大阶段&#xff0c;从学习到实践全流程提升物联网开发技能还…