写一个ajax程序就是如此简单

ajax介绍:

1:AJAX全称为Asynchronous JavaScript and XML(异步JavaScript和XML),指一种创建交互式网页应用的网页开发技术。

      2:基于web标准XHTML+CSS的表示;

      3:使用 DOM进行动态显示及交互;

      4:使用 XML 和 XSLT 进行数据交换及相关操作;

      5:使用 XMLHttpRequest 进行异步数据查询、检索;

程序员应用ajax的途经:

1:.Net下的AjaxPro,引入AjaxPro.2.dll,在前台页面JS调用后台页面的方法;

2:微软的AJAX组件,添加AjaxControlToolkit.dll,或者是ASP.NET AJAX;

3:开源的ajax框架。

4:自己写ajax脚本。

不过觉的前三种无论是哪一种,都觉的有点复杂,虽然它们如此强大,能做出很多特别优秀的无刷新效果,但开发人员都必须依赖它,开必人员只要学习怎么调用它就行,至于其中的原理大可忽略,即使你想学习它的原理,没有相当的js水平,怕是徒劳无功。如果需求并没有这么高,只是简单的通过无刷新实现访问后台代码然后操作DOM对象呢,还有必要引入这种大家伙吗?个人认识没有必要,理由如下:

1:有种杀鸡用牛刀的感觉;

2:引入第三方框架会使已有应用程序更加复杂;

3:js框架都不小,在每个网页中引入这些js文件对网络传输肯定会有部分影响。

4:如果框架中没有提供你要的功能,那又如何? 如何实现个性化定制?

ajax虽然流行了好几年了,但本人07年初才用上,当时公司同事有用ajaxPro的,但用过了实在了感觉不好用,有时往往会出现些莫名其妙的问题。后来在书店发现在《征服ajax系列》,才发现实现简单的ajax程序其实并不难,一个ajax程序处理过程如下:

第一:创建XMLHttpRequest,不同的浏览器创建的方式不同;

第二:发送请求。调用XMLHttpRequest的open()和send()方法:

          1:xmlhttp_request.open('GET', URL, true);

第一个参数:HTTP请求方式—GET,POST;

              第二个参数:请求页面的URL;

              第三个参数:请求是否为异步模式。如果是TRUE,JavaScript函数将继续执行,而不等待服务器响应。

          2:xmlhttp_request.send(null);

第三:服务器的响应。

1:告诉HTTP请求对象用哪一个函数处理这个响应。对象的onreadystatechange属性设置为要使用的JavaScript的函数名:xmlhttp_request.onreadystatechange =FunctionName;FunctionName是用JS创建的函数名,也可直接将JS代码创建在onreadystatechange之后,例如:

xmlhttp_request.onreadystatechange = function()
{
// JavaScript代码段
};

  

2:检查请求的状态。XMLHttpRequest 提供了readyState属性来对服务器响应进行判断。readyState的取值如下:0 (未初始化);1 (正在装载);2 (装载完毕);3 (交互中);4 (完成)。所以只有当readyState=4时,函数才可以处理该响应。具体代码如下:接着,函数会检查HTTP服务器响应的状态值。当HTTP服务器响应的值为200时,表示状态正常。 

if (http_request.readyState == 4) 
{ // 收到完整的服务器响应 }
else { // 没有收到完整的服务器响应 }

第四:处理从服务器得到的数据。有两种方式可以得到这些数据:

         1: 以文本字符串的方式返回服务器的响应;

2: 以XMLDocument对象方式返回响应

具体案例:我们有一批礼品想要送给用户,一般都会以文字列表的形式列出来,礼品名称上给个链接,当用户点击链接时弹出一个窗口显示这个礼品的详细描述信息,当用户选中下拉框按钮时判断这个礼品在送给用户前需要不需要用户填写地址,如果要则动态在页面加载相应的输入框。下面是两张效果图,一张时无需用户录入联系地址的,一张需要。

第一:引用封装好的XmlHttp.js,这个包含了创建XMLHttpRequest对象,以及发送请求与加载回调方法的函数,前端开发人员只需要传递简单的几个参数就可以实现异步调用,代码如下:


//------------------------------------------------------------------------------------------

//封装XMLHTTP的Request类的代码
var Request = new Object();
//定义一个XMLHTTP的数组 Request.reqList = [];
//创建一个XMLHTTP对象,兼容不同的浏览器 function getAjax()
{
    var ajax=false;
    try
    {
     ajax = new ActiveXObject("Msxml2.XMLHTTP");
    }
    catch (e)
     {
      try
      {
      ajax = new ActiveXObject("Microsoft.XMLHTTP");
      }
     catch (E)
      {
      ajax = false;
      }
    }
    if (!ajax && typeof XMLHttpRequest!='undefined')
    {
     ajax = new XMLHttpRequest();
    }
    return ajax;
}
//封装XMLHTTP向服务器发送请求的操作
//url:向服务器请求的路径;method:请求的方法,即是GET还是POST;callback:当服务器成功返回结果时,调用的函数
//data:向服务器请求时附带的数据;urlencoded:url是否编码;callback2;当服务器返回错误时调用的函数
Request.send = function(url, method, callback, data, urlencoded, callback2)
 {
    var req=getAjax();  //得到一个XMLHTTP的实例     //当XMLHTTP的请求状态发生改变时调用
    req.onreadystatechange = function()
    {
    // 当请求已经加载     if (req.readyState == 4)
    {
            // 当请求返回成功             if (req.status < 400)
            {
            // 当定义了成功回调函数时,执行成功回调函数
            if(callback)
                callback(req,data);
            }
            // 当请求返回错误             else
            {
                
                //当定义了失败回调函数时,执行失败回调函数
                if (callback2)
                callback2(req,data);
            }
            
            //删除XMLHTTP,释放资源             try {
                delete req;
                req = null;
            } catch (e) {}
        }
    }
    //如果以POST方式回发服务器     if (method=="POST")
     {
        req.open("POST", url, true);
        //请求需要编码         if (urlencoded)
            req.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');        
        req.send(data);
        Request.reqList.push(req);
    }
    //以GET方式请求
     else
    {
        req.open("GET", url, true);
        req.send(null);
        Request.reqList.push(req);
    }
    
    return req;
}
//全部清除XMLHTTP数组元素,释放资源 Request.clearReqList = function()
{
    var ln = Request.reqList.length;
    for (var i=0; i<ln; i++) {
        var req = Request.reqList[i];
        if (req)
        {
        try
        {
            delete req;
        } catch(e) {}
        }
    }
    Request.reqList = [];
}
//进一步封装XMLHTTP以POST方式发送请求时的代码 //clear:是否清除XMLHTTP数组的所有元素;其他参数的意义参见Request.send
Request.sendPOST = function(url, data, callback, clear, callback2)
{
    if (clear)
        Request.clearReqList();
    Request.send(url, "POST", callback, data, true, callback2);
}
//进一步封装XMLHTTP以GET方式发送请求时的代码 Request.sendGET = function(url,args, callback,clear, callback2)
{
    if (clear)
        Request.clearReqList();
    return Request.send(url, "GET", callback, args, false, callback2);
}

 第二:引用一个工具js:CommJM.js,一般是为了代码共享而引入的。


var controleID="";
var innerHtml="";
//给控件赋值
function $$(controleID ,innerHtml )
{
  var _controleID=$(controleID );
  _controleID .innerHTML=innerHtml ; }
//隐藏控件
function hideObject(controleID)
{
  var _controleID=$(controleID );
  _controleID.style.display = "none";
 
}
//显示控件
function showObject(controleID)
{
  var _controleID=$(controleID );
  _controleID.style.display = "block";
}
var controlsID="";
    //by minjiang 07-11-02
    function $(controlsID)
    {
      return document .getElementById (controlsID );     
    }

第三:创建ajax请求页面:ajax_promotion.aspx,把这个页面的HTML代码除了<%@ Page Language="C#"这行之外,全部删除。

第四:在ajax_promotion.aspx页面的后台代码中写相关业务操作。


//取得奖品ID
        string giftID = "";
        //当前促销活动方案ID
        string currentTarget = "";
        xmlProvider _xmlProvider = null;
        protected void Page_Load(object sender, EventArgs e)
        {
            
            this.action();         
        }
        private void action()
        {
            //业务处理类型
            string sAction = "";
            if (Request.QueryString["action"] != null && Request.QueryString["action"] != "")
            {
                sAction = Request.QueryString["action"].Trim();
            
            }
            switch (sAction)
            {
                case "getInput":
                    //判断用户选择的礼品是否需要录入联系方式
                    this.getInput();
                    break;
                case "getDescription":
                    this.getDescription();
                   break;          
            }       
        }
        /// <summary>
        /// 判断是否需要录入联系方式
        /// </summary>
        private void getInput()
        {
                   
        }
        /// <summary>
        /// 取某一奖品的详细说明信息
        /// </summary>
        private void getDescription()
        {
                 
        }

第四:在前端页面中实现异步调用。

第一:页面头部代码。


//引入相关js文件
<script language ="javascript" type ="text/javascript" src ="XmlHttp.js"></script>
<script language ="javascript" type ="text/javascript" src ="CommJM.js" ></script>
<script language ="javascript" >
//奖品ID
var giftID=1;
//根据奖品ID读取奖品的描述信息
function getDescription(giftID)
{
    var sUrl="ajax_promotion.aspx?id="+giftID+"&i="+Math.random()+"&action=getDescription";
   Request.sendGET(sUrl,null,getCallBack,true,null);
}
//根据奖品ID读取奖品的描述信息的回调方法
  function getCallBack(req,data)
  {
        //alert("进入回调方法");
         var strResult=req.responseText;
         //alert(strResult);
        if(strResult!="")
        {
           $$("jl01_layer",strResult);
    
        }      
  }
  //根据奖品ID取得这奖品是否需要录入用户的联系方式
  function getInput(giftID)
  {
       var sUrl="ajax_promotion.aspx?id="+giftID+"&i="+Math.random()+"&action=getInput";
       //alert(sUrl);
       Request.sendGET(sUrl,null,getInputCallBack,true,null);
  }
  //getInput回调方法
  function getInputCallBack(req,data)
  {
        //alert("进入回调方法");
         var strResult=req.responseText;
         //alert(strResult);
        if(strResult=="true")
        {
           showObject("<%= this .BlkBlackTabcontent_11 .ClientID %>");
    
        }
        else
        {
            hideObject("<%= this .BlkBlackTabcontent_11 .ClientID %>")
        }
  }
</script>

第二:页面代码:

<input id="ctl08_rbl_Gift_0" type="radio" name="ctl08$rbl_Gift" value="1" onclick="getInput('1');" />
<label for="ctl08_rbl_Gift_0">
<a href="#" onclick="cc(this,'jl01_layer','1')">
 礼品名称
</a>
</label>

总结:从整个过程来看,对于开发员来说代码量并不大,如果有了上面两个封装好的js文件,以后的开必就轻松多了,只关心复杂业务逻辑的处理以及页面效果,页面效果倒是需要额外的工作,最好具备一定的js能力。我们可以从其它js框架了抽取自己需要的部分放入自己的公用类库中,这样就形式了一套适合自己的js框架,方便又实用。

补充:这篇文章并不在于技术有多深,而在于一种工作模式,做适合自己项目的框架,远比用些看起来功能特别强大的框架来的方便。据园友的问题我想说明几点:

1:从性能上来讲,有的框架十来个js文件,而且还是压缩的,在网络传输时会有一定影响;

2:具体项目能调用的功能占整个框架功能的百分比。如果只是整个框架功能的10%,或者更少,引入框架值得吗?

3:自己开发脚本库时间长了,不也成了一个框架了吗?和其它的框架有什么区别呢?

第一:当然会成为一个框架;

第二:自己写的框架怎么会和别人写的框架一样呢?

<1>:自己的框架是自己根据具体项目具体需求来写的,很多框架中不实用的功能并不会引进来;

<2>:在调试上,自己的框架当然占优势,自己写的东西肯定能第一时间知道问题的出处。

4:自己开发框架,时间长了不也锻炼了自己的js能力吗?

5:本文并不是排斥框架,也不是说在项目中不能用框架,而是希望从实际项目考虑,全面比较框架在项目中优劣性。

             6:不要过分依赖框架,试想下在没有框架前,你的工作怎么办?用框架永远在别人之后。

7:ajax框架支持很多特别复杂的动画效果,这是手工完成难度特别大的地方,而且框架对程序员要求相对要抵,而且容易形成统一的代码风格,理性分析利弊再决定是否用框架。

8:自己写脚本,并不代表每个项目或者是每个页面都需要自己把所有方法都重写一次,当然会考虑到代码复用了,谁会在每个页面中都写 documemt.getelememtById啊,你不觉得烦,别人看起来也烦,如果封闭一个$()方法,不更好?而且这种方式都是从框架中学来的,要消化成自己的。

9:自己写脚本的目的:吸取多个框架的特点,取长补短,做适合自己的,如果你的项目中对动画什么的没有要求,那么就不会引入这些额外的没用的js,无论怎么写,肯定不能都自己写,需要借助已有成熟的产品,但不能拿来主义。

注:

本文引用:http://baike.baidu.com/view/1641.htm

写一个ajax程序就是如此简单的更多相关文章

  1. 学了C语言,如何利用CURL写一个下载程序?—用nmake编译CURL并安装

    在这一系列的前一篇文章学了C语言,如何为下载狂人写一个磁盘剩余容量监控程序?中,我们为下载狂人写了一个程序来监视磁盘的剩余容量,防止下载的东西撑爆了硬盘.可是,这两天,他又抱怨他的下载程序不好用,让我 ...

  2. 利用Python写一个抽奖程序,解密游戏内抽奖的秘密

    前言 本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. 作者: 极客挖掘机 PS:如有需要Python学习资料的小伙伴可以加点击下 ...

  3. [Java] 将标准字符流写入到文件中(通过控制台写一个html程序,并保存)

    package test.stream; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.Fi ...

  4. 用JAVA写一个多线程程序,写四个线程,其中二个对一个变量加1,另外二个对一个变量减1

    package com.ljn.base; /** * @author lijinnan * @date:2013-9-12 上午9:55:32 */ public class IncDecThrea ...

  5. linux常用终端指令+如何用vim写一个c程序并运行

    在装好ubuntu之后今天学习了一些linux的一些基础知识: windows里面打开命令窗口是win+r,在linux系统里面,ctrl+alt+t打开终端,今天的一些指令都是围绕终端来说的 首先s ...

  6. 我的第一个WCF程序,很简单适合我等菜鸟

    1.首先我罗列一下网站搜索并经过自己理解的WCF的含义: 1)WCF:(WIndows Communication Foundation)是由微软是由微软发展的一组数据通信的应用开发接口,可以翻译为W ...

  7. Linux内核学习--写一个c程序,并在内核中编译,运行

    20140506 今天开始学习伟大的开源代表作:Linux内核.之前的工作流于几个简单命令的应用,因着对Android操作系统的情愫,“忍不住”跟随陈利君老师的步伐,开启OS内核之旅.学习路径之一是直 ...

  8. 用tkinter写一个记事本程序(未完成)

    之前在看tkinter与python编程 ,后面学opengl就把那本书搁置了.几天没用tkinter,怕是基本的创建组件那些都忘记了,所以想着用tkinter试着写一下记事本程序.一开始的时候以为很 ...

  9. 基础概念(3):怎么写一个c程序?

    总结卡片: 遵循c语言的规则,即可写出c程序.规则下有两个重要概念:函数与变量.就好像游戏中的打仗,要考虑怎么打,谁来打."怎么打"就是流程,把流程封装起来就是函数,流程也叫算法. ...

随机推荐

  1. CSS样式“display:none”与“visibility:hidden”区别

    CSS样式“display:none”和“visibility:hidden”都可以实现将页面元素隐藏,但是具体的效果是有差别的!下面通过两个小实验来说明这种差异. 实验代码: <!DOCTYP ...

  2. 认识C++中的临时对象temporary object 分类: C/C++ 2015-05-11 23:20 137人阅读 评论(0) 收藏

    C++中临时对象又称无名对象.临时对象主要出现在如下场景. 1.建立一个没有命名的非堆(non-heap)对象,也就是无名对象时,会产生临时对象. Integer inte= Integer(5); ...

  3. matlab算法

    流水线型车间作业调度问题遗传算法Matlab源码流水线型车间作业调度问题可以描述如下:n个任务在流水线上进行m个阶段的加工,每一阶段至少有一台机器且至少有一个阶段存在多台机器,并且同一阶段上各机器的处 ...

  4. ubnt+ros 接入无线

    ubnt+ros 接入无线 一.ubnt配置(UBNT NanoStation LOCOM2 LOCO M2)1.ubnt接poe,转lan接到pc2.ubnt默认ip是192.168.1.20,用户 ...

  5. sqlserver 跨服务器访问数据

    需求:两个一模一样的表,分别分布在两个服务器的数据库上,现在要在一个表中,查看这两个表的内容,并让Id排序 1:在本地数据库查询分析器中,运行以下两段语句: --创建链接服务器 exec sp_add ...

  6. 转载:使用命令行启动VirtualBox虚拟机

    使用命令行启动VirtualBox虚拟机 装上VirtualBox就琢磨着如何让它开机自动启动,又或者能够通过命令行的形式直接启动指定的虚拟机. 看了下VirtualBox的官方文档,发现有一个命令可 ...

  7. winform基本控件----按钮

    这次来引用一个我们上课时候老师给的一个实验内容,来说一下winform程序设计中的按钮控件的使用.下面是我们老师给的实验内容. 实验目的: 掌握Winform的开发环境. 掌握窗体的创建和基本方法. ...

  8. 使用dojoConfig配置dojo(翻译)

    http://dojotoolkit.org/documentation/tutorials/1.10/dojo_config/index.html dojoConfig对象(原来是djConfig对 ...

  9. Android中如何监听GPS开启和关闭

    转自 chenming 原文 Android中如何监听GPS开启和关闭   摘要: 本文简单总结了如何监听GPS开关的小技巧 有时需要监听GPS的开关(这种需求并不多见).实现的思路是监听代表 GPS ...

  10. mysql 修改字段类型

    1.更改Float字段类型to Decimal ALTER TABLE 表名 MODIFY 字段名 decimal(10,2) not null default '0': 如: ALTER TABLE ...