• CS Coder学习asp.net5个月的最大感悟:从http的角度重新认识asp.net(二)——我理解的ajax(二)


      啊哈,时隔两个月,才开始写上一篇文章的后续,实在是惭愧.主要是年尾公司又来活了,忙得团团转,而且这段时间在自学mvc.我在上文中,提到过我对mvc框架的初步印象是:相比webform,算是回归了bs本质.这段时间的学习,也算是验证了这一点,没有了神(qi)奇(guai)的viewstate,所有前后端交互通过http请求向control或者其他的HttpHandel集中处理或是中转,整个流程的数据流转非常清晰.

      额,其实本来这个系列,我是很有一些东西想深入讲讲的,但学了mvc之后,才发现原来很多东西mvc框架早已经考虑到了,那我也就不讲太多了,本文即是这个系列的最后一文,还有,不知道小伙伴们看没看出来,我的标点符号全是半角的,额 这是因为我设置了强制使用半角,因为我被写代码过程中频繁的输入法转换弄烦了,如果给大家的阅读造成了一定程度的困扰,还请见谅. 好了,扯这么多废话,还不进入主题,估计看得人要骂人了.

      接上文:

      1,普通事件回发,请求提交人是form,http返回的数据就是整个页面的html代码,

    页面会刷新 会休眠2s RequestCount +1。

    这无疑是最不优美的做法,不仅网络数据传输量大,还需要重新请求一次页面head中声明引用的文件,虽然大部分情况有缓存,但还是会有一定的性能损耗。

    2事件回发 通过up的AsyncPostBackTrigger 提交 提交人是form,http返回被up包裹部分的html代码及一些参数信息(个人无责任猜测,是给ScriptManager准备的,然后ScriptManager通过js(运行在客户端)修改页面的html来完成信息无刷新显示),

    页面不会刷新 会休眠2s RequestCount +1

    3 jquery ajax提交 提交人就是它自己,不是表单(同时这个时候的ispostback是为false的,这也是我注释要说明的东西,ajax如果在后面处理,页面会认为是第一次加载,会执行if里面的逻辑了)

    最后 就是本文的肉戏了,页面无刷新 不会休眠   RequestCount 不变。

    查看http,返回的信息非常简单,就是response.write的信息,

    同时大家可以做个试验,把休眠两秒的逻辑注释,然后狂点两种无刷新按钮,明显的,jquery方式的ajax流畅的多。

    4,表单提交,如果在up里面和2一样 在外面和1一样。

    我先对这四种(第四种其实可以算是两种情况)情况做更进一步的解释.

    第一种,就是我们常见的,最原始的处理手法,相当于是重新请求的目标页面一次,众所周知,http请求是无状态的,它也不会管你是第几次访问,反正你发起了请求,我就按asp.net框架的流程,按你设置的httpmodel, httphandel给你处理一遍.           ,iis也是从转发request到响应response

    第二种呢? 首先我们可以知道,后台httphandel(我们自己写的页面类继承了Page,而Page实现了IHttpHandel接口,所以我这里说的httphandel就是我们写的页面类)处理http的逻辑,和第一种应该是一样的,为什么能够无刷新呢?

    我上面的猜测,虽说是猜测,但也不是我自己瞎猜的,

    给大家看下无刷新的http请求的数据

    可以发现,第一,只有一条http请求被发起,第二相比常规post提交,提交的请求头里面,有个&__ASYNCPOST=true的标识,第三,response返回的信息里面,只有区区5行数据,而这5行,很明显,就是被UpdatePanel包裹的控件的html代码,和一些它自己使用的参数. 

    大家再自行观察一下常规post提交的数据,对比是比较明显的.

    至于第四种,当提交按钮,没有被updatePanel包裹的时候,不受UP的影响,是完全等同于常规post提交了,如果放在up中,就会等同于第二种情况.

    这里额外提一个我自己使用up遇到过的问题,就是我页面里面有个隐藏控件(runat Server),动态保存当前某个状态,但是我局部刷新,同时后台去改变hiddenfiled的值,结果发现hf的值并没有被改变,其实是因为我hf控件没有放在up里面,不受它的管理.所以局部刷新的时候,hf的值还是原来的值,尽管这时候它在viewstate中的值是新的.

    好了,重点来了,第三种情况的无刷新是个怎么回事呢?

    先上jb

      可以看出,它提交的信息非常简洁,而且全是我们手工自定义进去的,没有其他多余的信息,可以想象,这种方式毫无疑问可以带来很大的灵活性.

    我解释下它的流程

    先看前端:

     $(document).ready(function () {
            $("#btnClentPost").click(function () {
                $.ajax({
                    type: "POST",
                    data: "act=updateResult&cmsg=append from ajax",
                    success: function (msg) {
                        $("#lblReault").html("this is from ajax server:" + msg);
                    }
                });
            });
        });

    这就发起了一个http请求,

     success: function (msg) {
                        $("#lblReault").html("this is from ajax server:" + msg);
                    }

    指的是,当httphandel处理完之后发回response,就会触发后面的匿名函数(事件)msg是response返回的信息,这个事件有几种重载,功能有细小差别,这里就不多谈了.

    当http请求被发起,目标httphandel就会接受到这个请求,这里需要这种强调下的是,我没有声明action,所以它默认的就是当前页面,你完全可以自己指定action(url),也就是httphandel,

    嗯,再引申一下,大家看到我不断提到httphandel,而没怎么提page aspx,ashx之类的字眼,其实也是为了贯彻我这系列文章的主线----http.

    关于aspx和ashx哪个好,是不是应该每个ajax请去都建立一个ashx,这些涉及到架构设计方面的东西,我这里也不多谈,不管是webservice 还是Page页,还是wcf接口,web api什么的,在我这里,一视同仁的认为是httpHandel,它们只干两件事

    1接收并处理request请求

    2返回response

    在我的例子中,httphandel就是后台Page页(再次强调,你可以任意定制它的httphandel)

     protected void Page_Load(object sender, EventArgs e)
            {
                string action = Request["act"];
                if (!string.IsNullOrEmpty(action))
                {
                    switch (action.ToLower())
                    {
                        case "updateresult":
                            ShowAjaxChange(Request["cmsg"]);
                            break;
                        case "getsectionpoint":
                            break;
                    }
                }
    //后续省略

    前台jquery发起了ajax请求之后,经过asp.net的pipeline和httpmodel的一系列处理流程,最终page_load被调用

    进入ShowAjaxChange

     //接收ajax传递过来的数据,并通过Response 做出处理
            private void ShowAjaxChange(string cMsg)
            {
                Response.Clear();
                Response.Write("S receive : " +cMsg +" Time : "+ DateTime.Now.ToString("HH:mm:ss fff"));
                Response.End();
            }

    我需要解释下 Response.End(); 这句话是非常重要的,它代表的是 强制结束本次request的后续流程,返回response,

    所以page_load里面我标记的  //后续省略   的代码,都是不会执行的,这也是我前面附加的一些奇怪说明的原因,也是它没有两秒休眠的原因.

    当然这里是因为我为了写代码方便,和让业务逻辑代码集中的一个做法,如果你们用其他类型的httphandel,可能就不需要这样做了,用前面总结的话来说,就是,你只需要正确的处理这个http请求,返回正确的response,就一切ok!!

    好了,这个系列算是写完了,也算是有始有终,可喜可贺啊!!(话说其实也只有3篇文吧,不过对于我这种写作小白来说,还是比较不容易的,呵呵)

    由于以前我博客是在csdn写的,直接导入过来,好像格式会有点问题,有时间再调整(但愿我有).

    还有的没说完的话,也留在后续的mvc系列里面讲吧,不过以我现在的mvc水平,大概是好久之后了.

    最后,前面我提到了,jquery的原生ajax,它的自定义性很强,其实用途也是非常广泛多样的,我也准备写一个我认为比较有趣的用例,算是这个系列的补充.

  • 相关阅读:
    菜根谭#245
    菜根谭#244
    菜根谭#243
    菜根谭#242
    菜根谭#241
    菜根谭#240
    菜根谭#239
    菜根谭#238
    菜根谭#237
    [转载]Linux 内核list_head 学习(一)
  • 原文地址:https://www.cnblogs.com/suijing/p/3486192.html
Copyright © 2020-2023  润新知