zoukankan      html  css  js  c++  java
  • Ajax学习笔记3种Ajax的实现

    Ajax:  Asynchronous JavaScript and Xml , 异步js脚本和xml , 常用来实现页面局部的异步刷新, 对提高用户体验有很大帮助. Xml在多语言时较有优势, 但Ajax技术实际上较多采用Json对象而不是Xml来处理数据.

    /##################/

    (一) Ajax历史....了解性知识

    Ajax归属于Web前端开发技术, 与javascript有着异常紧密的联系. Ajax就是一种实现异步通信无刷新的技术, 而这种技术可以有很多种实现方式. 浏览器的鼻祖网景(NetScape)公司最早发明了LiveScript脚本语言, 用来丰富网页元素的表现形式, 使网页能够呈现出动态效果. 随后的历次改版升级后就诞生了JavaScript语言, 与此同期微软(Microsoft)公司也看到互联网的前景, 开始涉足并发力于互联网行业, 推出了JScript语言, 可惜没有JavaScript成熟, 发展迟滞. 最终微软公司对互联网的决心促成了MS对NS的漫长曲折的收购历程.

    这里提一下, 动态HTML语言(Dynamic Hyper Text Markup Language)就是将javascript放在Dom树的元素节点中, 为元素提供动态展示行为.

    (二)Web前端开发的两个思路: a. JavaScript + XHR + CSS b. Flash ---> 浏览器插件 ---> Flex(Adobe); Silverlight4.0(MS)

    1. Ajax: 以MS的XHR(XMLHttpRequest)为核心 ---> Ajax

    2. flash: MicroMedia ---> 被Adobe收购 ---> flex (涵盖了ActionScript和Rich Internet Application等技术的组合)

    3. SilverLight: 微软为了抗衡flex而推出的SilverLight

    备注:
    为了能够在后台异步与服务器进行通讯, 微软在IE中添加了两个组件: 负责与服务器通讯的组件(XMLHTTPRequest)和XML的处理组件. 采用XML作为数据交换的载体, 在多语言处理时具有优势, 但xml的处理成本较高, 实际上Ajax中通常采用Json对象在客户端浏览器和服务器之间传递数据.

    网页的生成过程其实是由服务器上的一组程序来完成的, 这样为了在客户端的JS语言和服务器端的C#语言传递数据, .Net提供了Json序列化和反序列化器, 来提供服务器端C#对象和Json对象之间的转换. 而在浏览器端可以使用eval()函数获取服务器传递过来的Json串转化为Json对象.

    (三)Ajax解决什么问题

    我们都知道, 在客户端向服务器请求一个页面时, 服务器首先动态的计算并生成出页面, 然后再发给客户端. 客户端浏览器顺序编译并呈现页面.

    在没有Ajax时: 假如说页面有个用户验证控件, 那么在客户端浏览器呈现用户验证控件时, 会等待服务器的验证结果, 收到结果后才能继续呈现页面元素. 而这个验证过程通常要进行读取数据库等操作, 这就是所谓的同步方式. 而这种方式, 会造成网页呈现的假死状态.

    在使用Ajax后: 同样是验证控件, 客户端提交了验证请求后, 便继续顺序呈现其他元素. 当取得验证结果后, 由javascript在客户端修改内存中的DOM对象后并呈献给用户(注意: 这里修改的只是内存中的DOM对象, 而客户端接收的页面文件并没有修改). 这样, 使用异步的方式, 就不会出现假死状态, 同时客户端也节省了等待服务器返回结果时的时间开销.

    (四)Ajax的实现(3中Ajax的实现, 需要说明的是: Ajax能够实现的效果, 通过WebService都能实现.)

    1. Js中的Ajax异步调用: a.new b.onreadystatechange(处理responseText)  c.open(get方式和post方式) d.send      (同步调用: a.new b.open(get方式和post方式) c.send d.responseText)

    //ajax.html

    代码
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
    <title>Ajax of Javascript & jQuery</title>
    </head>
    <body>
    <a href="javascript:getData();">Javascript-Ajax: Click me</a><br />
    <br />
    <br />
    <input id="btn" type="button" value="jQuery-Ajax: Clike me"/>
    <hr />
    <div id="show">
    </div>

    <script type="text/javascript">
    function getData() {
    //创建XMLHttpRequest通信对象
    var xhr;
    if (window.ActiveXObject) { //标准情况下, 只能有两个ActiveXObject对象处理通信过程
    xhr =new ActiveXObject("Microsoft.XMLHTTP");
    }
    elseif (window.XMLHttpRequest) {
    xhr
    =new XMLHttpRequest();
    }
    else {
    thrownew Error("Ajax is not supported by this browser");
    }


    var elem = document.getElementById("show"); //用来显示处理结果
    //使用onreadystatechange事件处理结果
    xhr.onreadystatechange =function() {
    if (xhr.readyState ==4) { // readyState表示服务器响应状态. 4: 响应接收完毕
    if (xhr.status ==200) { // status 表示 http 请求的状态
    var json = xhr.responseText; //从请求中回应中获得json串
    var obj = eval("("+ json +")"); // 借助 eval 将 json 串转化为对象, 在客户端浏览器必须解析为js对象
    elem.innerHTML ="<span>"+ obj.name +"</span>";
    }
    }
    }

    //通过open设置请求方式
    xhr.open("get", "json.ashx", true); //默认为ture, false表示同步方式

    //发送请求
    xhr.send(null);

    /* 同步方式, false表示不适用异步方式
    xhr.open("get", "json.ashx", false);
    xhr.send(null);
    //处理结果
    alert(xhr.responseText);
    */
    }
    </script>

    <script src="jquery-1.4.2.js" type="text/javascript"></script>
    <script type="text/javascript">
    $(
    function() { //ready函数, 脚本加载完即执行, 也可以用$(...$("#btn").click...)();加载
    $("#btn").click(function showData() { //按钮上添加onclick事件, 事件处理方法为showData()
    $("#show").load("jquery.ashx"); //从jquery.ashx中获取数据元素(innerHTML的内容), 并显示在div中
    });
    });
    </script>

    </body>
    </html>

    然后还需要在项目中, 添加类似于json.ashx一般处理程序, 用于提供相关数据(如: 表格日历的绘制, 去数据库验证等操作)
    //json.ashx

    代码
    <%@ WebHandler Language="C#" Class="Json"%>

    using System;
    using System.Web;

    publicclass Json : IHttpHandler {

    publicvoid ProcessRequest (HttpContext context) {
    context.Response.ContentType
    ="text/plain";

    //对于静态内容, 需要禁用浏览器的缓存, 否则老是旧结果
    context.Response.Cache.SetCacheability(HttpCacheability.NoCache);

    string name ="Mike";

    string jsonFormat ="{{ \"name\": \"{0}\" }}"; //{{、}}是为了避免和Json中的{冲突而采用的特殊转义符

    string json =string.Format(jsonFormat, name);

    context.Response.Output.Write(json);
    }

    publicbool IsReusable {
    get {
    returnfalse;
    }
    }
    }

     //jquery.ashx

    代码
    <%@ WebHandler Language="C#" Class="jquery"%>

    using System;
    using System.Web;

    publicclass jquery : IHttpHandler {

    publicvoid ProcessRequest (HttpContext context) {
    context.Response.ContentType
    ="text/plain";
    context.Response.Cache.SetCacheability(HttpCacheability.NoCache);

    DateTime now
    = DateTime.Now;
    string jqueryFormat ="<span>{0}</span>";
    string jquery =string.Format(jqueryFormat, now);

    context.Response.Write(jquery);
    }

    publicbool IsReusable {
    get {
    returnfalse;
    }
    }
    }

    2.1 使用AjaxPro2:

     a.添加AjaxPro2类库(AjaxPro2.dll) b.webconfig中添加配置文件 c.在App_Code中创建类库文件(cs文件)提供Ajax服务, 并在页面对应的后台cs文件中注册Ajax(Page_Load事件中) d.在App_Code中的类库文件(cs文件中)编写带有Ajax标签的处理方法 e.在前台的aspx文件中使用脚本处理结果(修改内存中的DOM对象)并显示在页面上
    //b.webconfig中添加配置文件

    代码
    <location path="ajaxpro">
    <system.web>
    <httpHandlers>
    <add verb="*" path="*.ashx" type="AjaxPro.AjaxHandlerFactory,AjaxPro.2"/>
    </httpHandlers>
    <!--
    If you need to have Ajax.NET Professional methods running on the
    login page you may have to enable your own authorization configuration
    here.
    -->
    <!--
    <authorization>
    <deny users="?"/>
    </authorization>
    -->
    </system.web>
    </location>

     //c.在App_Code中创建类库文件(cs文件)提供Ajax服务, 并在页面对应的后台cs文件中注册Ajax(Page_Load事件中)
    //default.aspx.cs文件

    protectedvoid Page_Load(object sender, EventArgs e)
    {
    AjaxPro.Utility.RegisterTypeForAjax(
    typeof(CalendarServices)); //AjaxPro会根据注册的类型自动生成脚本
    }

     //d.在App_Code中的类库文件(cs文件中)编写带有Ajax标签的处理方法
    //CalendarServices.cs

    代码
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;

    publicclass CalendarServices
    {
    [AjaxPro.AjaxMethod]
    publicbool save(string date, string tile, string detail)
    {
    System.Threading.Thread.Sleep(
    5000); //用来测试异步
    returntrue; //这里为简单, 直接返回true
    }
    }

     //e.在前台的aspx文件中使用脚本处理结果(修改内存中的DOM对象)并显示在页面上
    //default.aspx文件

    代码
    <%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default"%>

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

    <html xmlns="http://www.w3.org/1999/xhtml">
    <head runat="server">
    <title></title>
    </head>
    <body>
    <form id="form1" runat="server">
    <div>
    日期:
    <input id="date" type="text"/><br />
    标题:
    <input id="title" type="text"/><br />
    详情:
    <textarea id="detail" cols="80" rows="5"></textarea>
    <hr />
    <input id="btn" type="button" value="确定"/>
    </div>

    <div>
    <script src="jquery-1.4.2.js" type="text/javascript"></script>
    <script type="text/javascript">
    $(
    function() {
    $(
    "#btn").click(function() {
    var date = $("#date").val();
    var title = $("#title").val();
    var detail = $("#detail").val();

    //由AjaxPro生成的js代理, 很像C#中类库的使用, 其中function(result)是异步的结果处理方法
    CalendarServices.save(date, title, detail, function(result) {
    if (result.error !=null) { //服务器上出现异常
    alert(result.error.Message);
    }
    if (result.value) { //服务器cs文件中的方法返回永真
    alert("服务器返回true! ");
    }
    });
    });
    });
    </script>
    </div>
    </form>
    </body>
    </html>

    2.2. 以前使用的老板Ajax(维护老项目可能用到, 其实与第2种很类似): a.引用Ajax框架类库 b. webconfig中添加配置 c.在App_Code中添加Ajax服务类, 并在CS文件中注册Ajax(Page_Load事件中) d.在App_Code中的CS文件中带Ajax标签的处理方法 e.按钮绑定触发JS的方法 f.JS处理方法

    //a. 引用Ajax框架的类库Ajax.dll

    //b. webconfig添加配置

    <httpHandlers>
    <add verb="POST,GET" path="ajax/*.ashx" type="Ajax.PageHandlerFactory, Ajax"/>
    </httpHandlers>

     //c. 在CS文件中注册Ajax(Page_Load事件中)

    Ajax.Utility.RegisterTypeForAjax(typeof(SysBase_UserEdit)); //SysBase_UserEdit是页面文件名称

    //d. 在App_Code中的CS文件中带Ajax标签的处理方法

    [Ajax.AjaxMethod]
    public DataSet getRoleData(int Roleid)
    {
    DataSet ds
    =new DataSet();
    ds
    = r.SelectRoleData(string.Format(" and id={0}", Roleid));

    return ds;
    }

    //e. 按钮绑定触发JS的方法

    this.DDLRole.Attributes.Add("onpropertychange", "onCommandInputPropertyChange();"); //在Page_Load事件中基于Attribute为按钮绑定方法, 在aspx文件中手动添加也可以

    //f. JS处理方法

    <script>
        function onCommandInputPropertyChange(){
            if (event.propertyName == "value"){
                var cmdInput = event.srcElement;
                if (cmdInput.value != 0){
                    //alert(cmdInput.value);
    		BindRoleName(cmdInput.value);	   
                }
            }
        }
        //绑定角色名
        function BindRoleName(RoleID){
    	//SysBase_UserEdit是aspx页面的名称
            SysBase_UserEdit.getRoleData(RoleID,get_AllName);
        }
        function get_AllName(response){
            var AllName = document.getElementById("DDLAjax");
            AllName.length = 0;
            if (response.value != null){ 
                var ds = response.value;
                if(ds != null && typeof(ds) == "object"){           
                    var name = ds.Tables[0].Rows[0].rolename;
    	        var id = ds.Tables[0].Rows[0].id;	        
    	        AllName.options.add(new Option(name,id));
    	    }
    	}
        }
    </script>
    

    3. VS2008集成的Ajax:

     a.VS2005的话需要安装插件(Microsoft ASP.NET 2.0 AJAX Extensions) b.紧挨着Form元素放置ScriptManager控件 c.在要刷新的table元素首位处, 使用UpdatePanel和ContentTemplate包起来 d.在table元素结尾处的ContenTemplate和UpdatePanel之间放置trigger元素, 注册Ajax触发按钮 e.引用类库Ajax2 f.VS2005需要配置webConfig
    //d. 在table元素结尾处的ContenTemplate和UpdatePanel之间放置trigger元素, 注册Ajax触发按钮(btn_Search, btn_Delete均为按钮)

    <Triggers>
    <asp:AsyncPostBackTrigger ControlID="AspNetPager1"/>
    <asp:AsyncPostBackTrigger ControlID="btn_Search"/>
    <asp:AsyncPostBackTrigger ControlID="btn_Delete"/>
    </Triggers>

    //f. VS2005需要配置webConfig

    代码
    <httpHandlers>
    <!-- 调用AjaxPro.2-->
    <add verb="POST,GET" path="ajaxpro/*.ashx" type="AjaxPro.AjaxHandlerFactory, AjaxPro.2"/>
    <remove verb="*" path="*.asmx"/>
    <add verb="*" path="*.asmx" validate="false" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
    <add verb="*" path="*_AppService.axd" validate="false" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
    <add verb="GET,HEAD" path="ScriptResource.axd" type="System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" validate="false"/>
    </httpHandlers>

    ============================分割线============================

    关于第一种: Js中的Ajax异步调用, 补充点东东, 不单独开篇了

    关于参数传递:
    1.
    get方式传参, 参数保存在URL中, 例如:
    xhr.open("get", "json.ashx?name=xxx", true);
    xhr.send(null);

    在服务端(json.ashx后台代码), 可以用HttpContext类型的参数对象context来获取, 获取方式context.Request.QueryString["name"]....等等(自己在调试状态下看)

    2.
    post方式传参, 参数保存在请求包的包体(Body)中, 例如:
    xhr.open("post","json.ashx",true);
    xhr.send("xxx");
    或者
    xhr.send("name=xxx");

    相应的服务器端(json.ashx后台代码), 针对2中"非键值对"、"键值对"有两种获取方法:
    非键值对: 用context.Request.InputStream获取, 如:
    System.IO.Stream stream = context.Request.InputStream;
    System.IO.StreamReader sr = new System.IO.StreamReader(stream);
    string strParam = sr.ReadToEnd();
    其中涉及编码转换的, 自己在调整下.

    键值对: 用context.Request.Form["name"]...获取

  • 相关阅读:
    BZOJ 1977: [BeiJing2010组队]次小生成树 Tree( MST + 树链剖分 + RMQ )
    BZOJ 2134: 单选错位( 期望 )
    BZOJ 1030: [JSOI2007]文本生成器( AC自动机 + dp )
    BZOJ 2599: [IOI2011]Race( 点分治 )
    BZOJ 3238: [Ahoi2013]差异( 后缀数组 + 单调栈 )
    ZOJ3732 Graph Reconstruction Havel-Hakimi定理
    HDU5653 Bomber Man wants to bomb an Array 简单DP
    HDU 5651 xiaoxin juju needs help 水题一发
    HDU 5652 India and China Origins 并查集
    HDU4725 The Shortest Path in Nya Graph dij
  • 原文地址:https://www.cnblogs.com/cs_net/p/1811831.html
Copyright © 2011-2022 走看看