我想知道__doPostBack的原理,请教一下各位大虾!
MS的东西除了好用外,有些地方是不明不白的!__doPostBack这个函数,是客户端的js脚本,既然是客户端的脚本,那应该是在客户端运行的,但是,在ie的源文件中,又没有显示调用__doPostBack函数的地方,由此我猜测这个函数是被浏览器调用的!但是,我自己写的__doPostBack函数却无法被浏览器调到,由此推断,想要浏览器调用__doPostBack函数,页面文件中可能会有点其它的“东西”,我猜:
1。__doPostBack可能是和viewstate一起工作的,viewstate有些信息,可以被浏览器解码后识别,用来确定是否需要调用页面上的__doPostBack函数;
2. __doPostBack可能和js的一个全局变量一起工作,由这个全局变量来决定,是否需要调用页面上的__doPostBack函数;或者还有其它的调用方法,请.net方面的大虾指点一下!
我想了解的内容包含以下几点:
a.简述一下__doPostBack这个客户端js函数,在浏览器中被调用的流程!请不要谈及server端!因为我目前的兴趣在了解客户端的函数调用流程!
b.能否写个简单的例子,在html中显示写一个__doPostBack函数,让函数中的alert,能弹出来<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
 <HEAD>
  <TITLE> New Document </TITLE>
 </HEAD>
 <BODY><form name="aspnetForm" method="post" action="http://Action.do" onsubmit="javascript:alert(2);" id="aspnetForm">
<div>
<input type="hidden" name="__EVENTTARGET" id="__EVENTTARGET" value="" />
<input type="hidden" name="__EVENTARGUMENT" id="__EVENTARGUMENT" value="" />
</div><script type="text/javascript">
//<![CDATA[
var theForm = document.forms['aspnetForm'];
if (!theForm) {
    theForm = document.aspnetForm;
}function __doPostBack(eventTarget, eventArgument) {
alert(eventTarget);// this "alert" is not invoked
alert(eventArgument);// this "alert" is not invoked
    theForm.__EVENTTARGET.value = eventTarget;
    theForm.__EVENTARGUMENT.value = eventArgument;
    theForm.submit();
}
//]]>
</script>
  <INPUT TYPE="submit" value ='dddd' id="sss" onclick="javascript:alert(1);"/>
</form> </BODY>
</HTML>c.请不要大谈修改__doPostBack函数的坏处,我不会在代码中乱改这个函数的,我现在只想知道调用流程;
d.也不需要说“这是asp.net的特性,用就行了,不需要管他是怎么调用的”之类的话!我之前也查了doPostBack相关的帖子,基本上,大家都是讨论的如何使用,客户端,服务器端如何配合使用,担对于函数的调用流程很少提及,也许是ms透露的太少,也许是大家没空去看ms的源代码,反正,请各位大虾帮个忙,把这个调用流程的问题讨论清楚!
谢谢!

解决方案 »

  1.   

    __doPostBack是.net的吗??看上面像js的啊。。根ms有关系吗??
      

  2.   

    搜索到一个简单讲解:http://www.newasp.net/tech/net/12641.html
      

  3.   

    以及另一部分讲解:http://www.cn-web.com/cnweb/0/166/article/
      

  4.   

    你的代码中并没有涉及页面回发,没有任何地方调用 _doPostBack,所以页面中虽然有这个函数定义但是没有调用。
      

  5.   

    这个几句话还真不好说啊...要了解_doPostBack函数就要了解ASP.NET的POSTBACK机制,这个函数的本意是用于ASP.NET框架内部使用的,它让ASP.NET的服务器端控件有了向服务器发送请求的能力。ASP.NET中的服务器控件在提交的时候就会调用_doPostBack函数以提交数据到服务器。这里所说的数据不光是表单中的数据,还有与控件事件相关的内容以及视图状态等辅助数据,这些辅助数据都是通过页面上的隐藏域来保存的,通过这些数据服务端就知道要使用哪一个事件处理函数如果楼主用过ICallbackEventHandler接口来写过AJAX应用的话可能更好更解一些,因为IPostbackEventHandler和ICallbackEventHandler这两个接口的用法是很相似的建议楼主了解一下ASP.NET的控件开发
    可以去看看黄忠诚的那本《深入剖析ASP.NET组件开发》这本书,可能你在看了前面几十页后就可以很好地理解ASP.NET中的POSTBACK机制了。
      

  6.   

    楼主的页面中没有调用_doPostBack是因为页面中没有runat=server的ASP.NET控件
      

  7.   

    每一次提交页面都离不开__doPostBack,这个js函数是自动执行的。
      

  8.   

    每一次提交页面都离不开__doPostBack,这个js函数是自动执行的。
      

  9.   

    谢谢各位大虾的指导!
    我用
    <INPUT TYPE="submit" value ='dddd' id="sss" onclick="javascript:alert(1);"/>
    这个来post页面的,还有,你给的两个例子,基本上也是如何应用这个__doPostBack我大概也是这么想的,所以我开始认为,客户端和服务器端有某种联系,因为http是无状态的协议,所以,客户端和服务器端保存状态只能通过3种方法:客户端的cookie,服务器端的session,或者页面上的数据如viewstate这类东西!个人认为session应该不太好,请求多的话要么服务器挂掉,要么无法响应请求;cookie我不清楚是否好用,但是我总觉得没viewstate好用!
    OK,加入我加了runat=server,ie中_doPostBack也被调用到了,那谁能告诉我,是谁调用了这个_doPostBack?ie内部吗?
    因为发送到客户端的页面都是静态的,再加一点js脚本,所以,如果加了runat=server,_doPostBack能被调用到,那么,一定有其它方法,使得我在客户端能模拟出这种效果,而不需要服务器端的配合(加了runat=server,这个页面在发送到客户端之前,可能要经过服务器的修改,把里面的aps控件换成html控件,也许是这一步,导致显式的_doPostBack是否被调用!那么我们就来模拟一下这一步)
      

  10.   

    以下内容转载自:http://www.guodong.net/blog/article.asp?id=198
    这里需要提一下的是,asp.net编程提供了服务端控件和客户端控件的说法,其实还是脱离不了HTML的本质,客户端和服务端需要交互必须要提交,提交有两种方式get和post,get就是通过向服务端发送连接地址,服务端通过地址的参数来获得信息的,一般这些参数都是明文,能在浏览器地址栏看到。而 post是通过表单的input等元素提交到服务端的页面的,这些数据一般是看不到的。asp.net的服务端控件其实就是对一般的HTML控件做了个包装,大体是通过隐藏控件提供控制的参数的。
    这里介绍一个常用的函数_doPostBack,这个函数如果如果是ASP.Net render出来的页面就是自动产生这个函数,比如有带autopostback属性的控件,且其属性为true的页面,带编辑列的datagrid页面。
    __doPostBack 是通过__EVENTTARGET,__EVENTARGUMENT两个隐藏控件向服务端发送控制信息的,__EVENTTARGET为要调用控件的名称,如果要调用的控件是子控件,用''$'或':'分割父控件:子控件,__EVENTARGUMENT是调用事件时的参数
    下面演示下如何调用后台事件:
    1.新建工程
    2.拖入一个服务端Button1,一个DropDownList1和一个客户端Button
    3.设置DropDownList1的AutoPostBack属性为True,Button1的Visible为False
    4.双击Button1,在事件里写下Response.Write("hello:" );
    5.页面的HTML里找到客户端Button,写入onclick="__doPostBack('Button1','')"
    6.编译,运行,点击Button是不是出现了"Hello"
    7.查看源代码,发现里面多了下面行 <script language="javascript">
    <!--
        function __doPostBack(eventTarget, eventArgument) {
            var theform;
            if (window.navigator.appName.toLowerCase().indexOf("netscape") > -1) {
                theform = document.forms["Form1"];
            }
            else {
                theform = document.Form1;
            }
            theform.__EVENTTARGET.value = eventTarget.split("$").join(":");
            theform.__EVENTARGUMENT.value = eventArgument;
            theform.submit();
        }
    // -->
    </script> 
    值得注意的是,_doPostPack的第一个参数是大小写不敏感的细心的人会发现,在__doPostBack里,提交调用的是 theform.submit(),这样就导致对Form的onsubmit事件校验失效了,幸好这个问题在asp.net 2.0已经修复了。这里提供一个替换的解决办法,在Form的最下面插入下面的代码,这段代码在保证不管是不是render出来的页面均有效
    [code=JScript]
    <script language="javascript">
    <!--
        function __doPostBack_Ex(eventTarget, eventArgument)
        {
            var theform;
            if (window.navigator.appName.toLowerCase().indexOf("netscape") > -1) {
                theform = document.forms[0];
            }
            else {
                theform = document.forms[0];
            }        if(!theform.__EVENTTARGET)
            {            
                theform.appendChild(document.createElement("<input type='hidden' name='__EVENTTARGET'>"));
            }
            
            if(!theform.__EVENTARGUMENT)
            {            
                theform.appendChild(document.createElement("<input type='hidden' name='__EVENTARGUMENT'>"));                        
            }
            
            theform.__EVENTTARGET.value = eventTarget.split("$").join(":");
            theform.__EVENTARGUMENT.value = eventArgument;
            if ((typeof(theform.onsubmit) == "function"))
            {
                if(theform.onsubmit()!=false)
                {
                    theform.submit();    
                }
            }
            else
            {            
                theform.submit();    
            }
            
            function __doPostBack(eventTarget, eventArgument)
            {
                __doPostBack_Ex(eventTarget, eventArgument);
            }
                }
    // -->
                </script>[/code]
      

  11.   

    再次感谢liuyeede,这个文章我看过了,但是只说了使用方法,没讲到原理上!微软的东西,很多好东西要自己挖掘的:))
      

  12.   

    再次感谢liuyeede,这个文章我看过了,但是只说了使用方法,没讲到原理上!微软的东西,很多好东西要自己挖掘的:))
      

  13.   

    http://www.cnblogs.com/tonyman/archive/2007/02/13/648994.aspx
      

  14.   

    在ASP.NET页面PostBack的过程中,调用_doPostBack仅仅是提交页面的开始,之后还会执行一系列的事件,比如OnInit、OnPreRender、Load等。
    你迷惑的可能是为什么_doPostBack会自动生成?当页面第一次Render到客户端时,继承自Control类控件最终在客户端呈现Html代码和相关的JavaScript脚本。你可以反编译Control类看一下它的代码。
      

  15.   

    __doPostBack其实就是通过
    <input type="hidden" name="__EVENTTARGET" id="__EVENTTARGET" value="" />
    <input type="hidden" name="__EVENTARGUMENT" id="__EVENTARGUMENT" value="" />
    这两个隐藏控件将你的值传到后台,比如__doPostBack("btn1","aaa"),
    __doPostBack会将"btn1"和"aaa"分别赋值给上面2个隐藏控件,然后通过form.submit()提交form,
    这样我们后台可以通过
    Request["__EVENTTARGET"]获得"btn1"
    Request["__EVENTARGUMENT"]获得"aaa"
    html是静态页面,当然不能实现了
      

  16.   

    看来大家始终是在“外围”绕来绕去!
    我不是迷惑“为什么_doPostBack会自动生成”,整个页面都是服务器响应回来的东西,服务器想怎么改页面都可以,就是在里面加个_doPostBack222,_doPostBack333也不奇怪,反正是服务器回应的东西,只要符合html语法,浏览器都能认识!现在谈论的是_doPostBack在客户端是被谁调用的,不必看服务器端的控件!我知道__doPostBack会用__EVENTTARGET和__EVENTARGUMENT向服务器端传数据,我现在不要知道__doPostBack如何跟服务器交互的,我要知道的是,客户端谁调用了__doPostBack函数,并且,我要是想自己写个__doPostBack函数,在浏览器中被调到,该怎么写!!请各位大虾把眼光集中在客户端,不要考虑服务器端!因为我的问题都是在浏览器这边的!
    现在我重新把问题整理一下:
    1.浏览器中__doPostBack函数被谁调用了
    2.自己写个html的页面,能否模拟__doPostBack被调用的过程?如果不能,请只从浏览器的角度说一下为什么;能模拟的话,请帮忙写个最简单的例子,在__doPostBack函数中写个alert,并且让alert能弹出来!
      

  17.   


    我知道__doPostBack会用__EVENTTARGET和__EVENTARGUMENT向服务器端传数据,我现在不要知道__doPostBack如何跟服务器交互的,我要知道的是,客户端谁调用了__doPostBack函数,并且,我要是想自己写个__doPostBack函数,在浏览器中被调到,该怎么写!! 
    -------------------------------------
    function __doPostBack(eventTarget, eventArgument) {
        alert(eventTarget);// this "alert" is not invoked
        alert(eventArgument);// this "alert" is not invoked
        theForm.__EVENTTARGET.value = eventTarget;
        theForm.__EVENTARGUMENT.value = eventArgument;
        theForm.submit();}//这个不是所谓的交互吗?
      

  18.   

    1.浏览器中__doPostBack函数被谁调用了
    A:被你放到界面上的控件调用了2.自己写个html的页面,能否模拟__doPostBack被调用的过程?如果不能,请只从浏览器的角度说一下为什么;能模拟的话,请帮忙写个最简单的例子,在__doPostBack函数中写个alert,并且让alert能弹出来!
    A:
    <HTML>
     <HEAD>
      <SCRIPT LANGUAGE="JavaScript">
      <!--
    function __doPostBack(eventTarget, eventArgument) { 
        theForm.__EVENTTARGET.value = eventTarget; 
    theForm.__EVENTARGUMENT.value = eventArgument; 
    theForm.submit();
    }
      //-->
      </SCRIPT>
     </HEAD> <BODY>
      <form id="theForm" name="theForm" method="POST">
      <input type="hidden" id="__EVENTTARGET">
        <input type="hidden" id="__EVENTARGUMENT">
    <input type="button" value="Invoke" onclick="__doPostBack('ButtonID','')" />
      </form>
     </BODY>
    </HTML>
    这样不就行了吗,调用__doPostBack函数的过程和你写其它任何的JS函数是完全一样的,楼主是不是也把这个想得太复杂了?
    楼主看看一个ASPX页面的源代码就知道了。
      

  19.   

    thanks,但是您把我的意思理解反了吧,交互我是知道的!不过我现在不要研究交互!只能这样直接手动调用__doPostBack函数吗?
    如果真如您说的这样,这100分都给你!
    现在那csdn的登陆页面做个例子,http://passport.csdn.net/UserLogin.aspx,查看源文件,里面有__doPostBack函数,请问是在哪里调用的呢?我找了这个页面包含的脚本,里面也没有,还是我没找全!
      

  20.   

    怎么说是只能通过手动调用?当你提交数据时,由提交数据的ASP.NET控件调用。再说了,没有手动,哪有相对的自动?所以我这里就不说自动调用了。
      

  21.   


    那两个文章中的例子都是调用GetPostBackEventReference方法在客户端html中插入了调用 _doPostBack的代码。asp.net几乎所有控件都是调用这个方法来自动生成客户端回发代码,但是唯一例外大概就是Button控件,当UseSubmitBehavior属性值为true的时候(这是默认值)它生成调用submit()的普通的页面post提交代码,而不是_doPostback回发代码。如果你将这个属性设置为false,则可以看到正常地生成调用_doPostback客户端代码。你的html中就没有调用_doPostback的地方,但是有这个函数的声明,很可能就是因为整个页面只有这样一个并不调用回发代码的Button控件造成的。我这里是把调用_doPostback提交的方式叫做回发,没经过_doPostback而直接提交的方式叫做提交。或许你会把所有提交到本页面的提交都叫做回发,这似乎确实没有什么标准叫法。但是总之,不是仅仅必须调用_doPostback才可以提交数据的。
      

  22.   

    谢谢各位,又离目标近了一点:))
    嗯,调用_doPostBack的代码应该是在render的时候,用GetPostBackEventReference方法生成的,然后再发给客户的browser的!
    请问一下,为什么render后的页面中找不到调用的_doPostBack的地方呢?也许页面上有调用的地方,重点是调用的代码在何处,比如:
    function __doPostBack(...){...}//函数定义
    <input type="button" value="Invoke" onclick="__doPostBack('ButtonID','')" /> 某处调用__doPostBack
    以csdn的登陆页面为例,http://passport.csdn.net/UserLogin.aspx,源文件里面有__doPostBack函数,请问是在哪里调用的呢?我找了这个页面包含的脚本,里面也没有!
      

  23.   


    它从未调用这个方法。页面上有这个方法定义是多余的。csdn是个技术实现相当混乱的网站。
      

  24.   

    thanks,sp1234,就是说,如果__doPostBack被调用了,那它一定是被显式调用的,是吧!?
    就像20楼的例子那样?!
      

  25.   

    那不能叫手动调用,我这里写这个例子,你看起来是手动地调用了__doPostback,但实际上__doPostback函数是ASP.NET控件产生的,而不是由你写上去的,这个是ASP.NET控件的机制。开发人员要做的只是把ASP.NET放在页面上然后写出各个事件的处理程序