下面是google找到的结果,原文满天飞,就不写出处了。
ajax(Asynchronous JavaScript and XML)是结合了Java技术、XML以及JavaScript等编程技术,可以让开发人员构建基于Java技术的Web应用,并打破了使用页面重载的惯例。
Ajax是使用客户端脚本与Web服务器交换数据的Web应用开发方法。这样,Web页面不用打断交互流程进行重新加裁,就可以动态地更新。使用Ajax,用户可以创建接近本地桌面应用的直接、高可用、更丰富、更动态的Web用户界面。
异步JavaScript和XML(AJAX)不是什么新技术,而是指这样一种方法:使用几种现有技术——包括级联样式表(CSS)、 JavaScript、XHTML、XML和可扩展样式语言转换(XSLT),开发外观及操作类似桌面软件的Web应用软件。实现Ajax的所有组件都已存在了许多年。Adaptive Path的用户体验战略部门主管兼创办合伙人Jesse James Garrett今年2月发表在Adaptive Path网站上的一篇文章中杜撰了这个术语。
异步这个词是指AJAX应用软件与主机服务器进行联系的方式。如果使用旧模式,每当用户执行某种操作、向服务器请求获得新数据,Web浏览器就会更新当前窗口。
如果使用AJAX的异步模式,浏览器就不必等用户请求操作,也不必更新整个窗口就可以显示新获取的数据。只要来回传送采用XML格式的数据,在浏览器里面运行的JavaScript代码就可以与服务器进行联系。JavaScript代码还可以把样式表加到检索到的数据上,然后在现有网页的某个部分加以显示。
在面向消费者的诸多应用当中,Google的Gmail和Google Maps就是最常见的例子。在Gmail当中,AJAX负责如何开启线程会话,以显示不同邮件的文本内容。而在Maps当中,AJAX允许用户以一种似乎无缝的方式拖拉及滚动地图。
还有雅虎的Flickr像片共享应用和亚马逊网站的A9搜索引擎。另外,雅虎新的Web邮件服务可能很快就会吸引AJAX支持者的莫大关注,这项服务基于雅虎收购Oddpost后得到的技术。
这些UI都充分地使用了后台通道,也被一些开发者称为“Web 2.0”,并导致了大家对Ajax应用兴趣的猛涨。
然而,AJAX应用软件厂商越来越把目光瞄准了企业。譬如说,Scalix的Web Access电子邮件应用软件其实比微软Outlook自己的Web邮件界面更像Outlook。
不过AJAX应用软件的适用领域具有一定的局限性。因为它们利用了一些最新的Web技术,所以只能在某些Web浏览器里面运行——不过AJAX适用的浏览器正越来越多。
另外一篇,ajax的罪恶,出自
http://www.duduwolf.com/post/115.asp
罪之一:对搜索引擎的支持不好
这其实更像一个大大的讽刺,AJAX的鼻祖是Google,但却对Google自己支持最不好了,GMail主界面除过Top和Bottom外没有一个链接就是最形象的讽刺了。虽然Mail本身是个私人的应用系统,但这个无链接的设计界面恰恰给AJAX开了个坏头。Flash也有同样有这个毛病。没有链接的web就像森林中迷路的羔羊,这句看似广告语,其实是web设计的根本原则。
罪之二:编写复杂、容易出错
javascript本是是个轻量级的小东西,现在被强迫重用起来,负担可想而知。javascript对OOP的支持很少,这就限制了 javascript代码的可重用可封装等等,从Google Mpa还是其他一些应用中能看到的都是无数的<script src="..."></script>这样的文件包含,这些除了让程序员头昏的更快点,一点好处都没有。更可怕的是在 javascript中竟然没有一款顺手的Debug软件,很多写js的老手到今天还是用最原始的alert("")来调试,splinetech JavaScript HTML Debugger 算是一个看起来还像个样子的调试器吧,可惜不是免费的,几十大刀让我这种穷人只能望而生叹了。
罪之三:冗余代码更多了
和上面说的差不多,层层包含js文件是AJAX的通病,再加上以往的很多服务端代码现在放到了客户端,所以每次打开一个页面会包含很多的无用的js文件也一同下载下来。虽然宽带越来越普及,但是减少代码冗余还是每个web设计者的必修课。
罪之四:破坏了Web的原有标准
什么叫破坏web标准?<span onclick="location.href='detail/';">点击查看全部</a>,这就是破坏了web标准。好好的A标签放着不用,偏要用span。这种例子很多,flickr中的标题单击后可以更改,这虽然(也包括我)是大家一致叫好觉得方便的设计,但同时这也是歧义了 web元素本身的含义,物是人非这个词不知道用的合不合适?
罪之五:缺少一个没有标准之争、没有back和history的浏览器
哈哈,这句话语有点讽刺意义。现在的浏览器市场,不管是IE还是FireFox还是Opera等等。浏览器和浏览器之间的差异一直都是web设计者心中永远的痛,支持的css不一样,支持的客户端脚本不一样,有的竟然连客户端脚本的用法都有不同。这让程序员非常苦恼,最明显的就是调用 xmlhttprequest了,req=(window.XMLHttpRequest)?new XMLHttpRequest():new ActiveXObject("Microsoft.XMLHTTP");这段创建xmlhttp对象的代码就是为了适应IE和非IE两天阵营的浏览器的经典例子。说是没有back和没有history的浏览器,这也是一个讽刺,主要是指在AJAX下点击链接是不Redirect页面,所以不存在后退和前进了,同样,没有后退和前进也就无存找浏览历史纪录了。back和history存在的根本就是url的改变,在AJAX下人们发现不改url也同样能达到内容改变这个酷酷的特点,何乐而不为呢?look http://www.dux2005.org/和http://www.zagodesign.com/,我承认这两个站确实做得非常棒,但除了酷酷的感觉外,毫无用处。
罪之六:XML只是用来打幌子
xml从诞生那天起就被一致看好,大有非xml不娶之势,我想Jesse James Garrett也是为了趋于流行才把xml强行加入ajax的吧。xml有一个致命的缺点,那就是加载的资源耗费,这好像是所有平台下xml的通病。google map虽然是Jesse James Garrett推荐的AJAX的品牌代言人,但是gmap并没有用xml,而是用了原生的javascript数组,我自己在用AJAX从服务端传回数据时也从来不用 XML,因为它让我更繁琐让系统更慢。服务端首先要调用xml对要传输的数据进行封装,客户端得到数据后再调用xml进行解析,简直是画蛇添足。AJAX 的一个重要特点是要身法轻盈,数据的传输尽量单一和简陋,如果确实需要传输大量复杂的数据,也应该通过多次调用传回。
罪之七:世界这么大却找不到自己的家
AJAX适用于什么?能干什么?能带来什么?在网站上用AJAX那是笑话,除非像Google Map和Flickr这样的专业领域的网站外,普通网站根本没必要用这个技术;在庞大的企业应用市场估计还能有AJAX的一点容身之地,不过在MS、 SUN不会看着AJAX这个野孩子来在他们的地盘上撒泼的,如果大家都用AJAX,那java给谁卖?.net给谁卖?所以AJAX在企业应用也不是长久之地。所以,AJAX现在找不到自己合适的位置是个很大的尴尬。疑病乱投医,最近把AJAX的矛头指向Flash和Applet就是一个例子。
当然,我也不是要把AJAX扁的一无是处,我本人就非常喜欢这门技术,它能让web设计者的眼球更加宽广,让一些大胆的设计成为现实,但是我也会很冷静的小心翼翼的利用这个利器,利器虽好,一不留神刺伤的是自己。
原文有评论,作者提到的javascrpt以及js面向对象化不好是错误的,他们是面向对象的脚本语言的典范。
简而言之,ajax,就象flash一样,有用,但是会加大对于硬件的要求,同时也需要更好的技术员,象gmail用这个,那是因为它的老板是google。原文作者使用的似乎也是zblog,而且加工了一下。
象zblog这样的程序都只用了一点点无刷新技术,说明ajax不是必要的。
至于其中的元素,象javascript、xml、css等,他们原先的作用就很大,就算没有ajax,也不至于失业。
至于常常提到的web2.0,对于技术的要求也高,但是无论是blog、rss这些形式还是ajax这些技术,和2.0这个概念应该没有很大的亲缘。
好了,最好在找一个简单的ajax页面范例来收藏一下。
还是来自于落伍者论坛的.......,落伍牛人真多啊。其实我也会写,只是很晚了,我要睡觉了哦。
//niceidea 签名留念
实例1: 注册模块
假如我要构造一个会员注册页面,传统的方法是客户端填写注册内容,然后交给服务器端处理,然后返回注册结果
假设我注册一个ID为 tony的会员,而数据库中已经存在这个ID,整个流程将是这样的:
1. 客户填写注册表单(当然,你可以加入javascript已检测客户端填写表单是否正确),并表明要求注册的ID为tony
2.发送表单至处理页面(客户端刷新一次,并等待)
3.服务器端处理表单,检测tony这一ID已经注册,返回"ID已注册信息"(视程序而定,客户端刷新一次或不刷新)
4.重新跳转至注册页面(客户端再刷新一次)
OMG, 这最少要刷新2次,还得要我等上半分钟,如果不是很重要,我情愿不注册了!
不刷新? 不等待? 让ajax来帮你吧
Step1:
已存在数据库
会员表单 member
列
ID 登陆ID
Password 登陆密码
其中已经有一行 ID为 tony 的数据
Step2:
构造注册表单 reg.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>注册</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
</head>
<body>
<div id="msg"></div>
ID: <input type="text" id="regid" /><br />
Password: <input type="password" id="regpassword" /><br />
<input type="submit" id="regsubmit" />
</body>
</html>
Step3:
XmlHTTPrequest调用 javascript ajax.js
//功能: 根据浏览器调用支持的XMLHTTPREQUEST
// IE support
if (window.ActiveXObject && !window.XMLHttpRequest)
{
window.XMLHttpRequest = function()
{
var msxmls = new Array('Msxml2.XMLHTTP.5.0','Msxml2.XMLHTTP.4.0','Msxml2.XMLHTTP.3.0','Msxml2.XMLHTTP','Microsoft.XMLHTTP');
for (var i = 0; i < msxmls.length; i++)
{
try
{
return new ActiveXObject(msxmls[i]);
}
catch (e)
{
}
}
return null;
};
}
// Gecko support
/* ;-) */
// Opera support
if (window.opera && !window.XMLHttpRequest)
{
window.XMLHttpRequest = function()
{
this.readyState = 0; // 0=uninitialized,1=loading,2=loaded,3=interactive,4=complete
this.status = 0; // HTTP status codes
this.statusText = '';
this._headers = [];
this._aborted = false;
this._async = true;
this._defaultCharset = 'ISO-8859-1';
this._getCharset = function()
{
var charset = _defaultCharset;
var contentType = this.getResponseHeader('Content-type').toUpperCase();
val = contentType.indexOf('CHARSET=');
if (val != -1)
{
charset = contentType.substring(val);
}
val = charset.indexOf(';');
if (val != -1)
{
charset = charset.substring(0, val);
}
val = charset.indexOf(',');
if (val != -1)
{
charset = charset.substring(0, val);
}
return charset;
};
this.abort = function()
{
this._aborted = true;
};
this.getAllResponseHeaders = function()
{
return this.getAllResponseHeader('*');
};
this.getAllResponseHeader = function(header)
{
var ret = '';
for (var i = 0; i < this._headers.length; i++)
{
if (header == '*' || this._headers[i].h == header)
{
ret += this._headers[i].h + ': ' + this._headers[i].v + '\n';
}
}
return ret;
};
this.getResponseHeader = function(header)
{
var ret = getAllResponseHeader(header);
var i = ret.indexOf('\n');
if (i != -1)
{
ret = ret.substring(0, i);
}
return ret;
};
this.setRequestHeader = function(header, value)
{
this._headers[this._headers.length] = {h:header, v:value};
};
this.open = function(method, url, async, user, password)
{
this.method = method;
this.url = url;
this._async = true;
this._aborted = false;
this._headers = [];
if (arguments.length >= 3)
{
this._async = async;
}
if (arguments.length > 3)
{
opera.postError('XMLHttpRequest.open() - user/password not supported');
}
this.readyState = 1;
if (this.onreadystatechange)
{
this.onreadystatechange();
}
};
this.send = function(data)
{
if (!navigator.javaEnabled())
{
alert("XMLHttpRequest.send() - Java must be installed and enabled.");
return;
}
if (this._async)
{
setTimeout(this._sendasync, 0, this, data);
}
else
{
this._sendsync(data);
}
};
this._sendasync = function(req, data)
{
if (!req._aborted)
{
req._sendsync(data);
}
};
this._sendsync = function(data)
{
this.readyState = 2;
if (this.onreadystatechange)
{
this.onreadystatechange();
}
var url = new java.net.URL(new java.net.URL(window.location.href), this.url);
var conn = url.openConnection();
for (var i = 0; i < this._headers.length; i++)
{
conn.setRequestProperty(this._headers[i].h, this._headers[i].v);
}
this._headers = [];
if (this.method == 'POST')
{
// POST data
conn.setDoOutput(true);
var wr = new java.io.OutputStreamWriter(conn.getOutputStream(), this._getCharset());
wr.write(data);
wr.flush();
wr.close();
}
// read response headers
// NOTE: the getHeaderField() methods always return nulls for me :(
var gotContentEncoding = false;
var gotContentLength = false;
var gotContentType = false;
var gotDate = false;
var gotExpiration = false;
var gotLastModified = false;
for (var i = 0; ; i++)
{
var hdrName = conn.getHeaderFieldKey(i);
var hdrValue = conn.getHeaderField(i);
if (hdrName == null && hdrValue == null)
{
break;
}
if (hdrName != null)
{
this._headers[this._headers.length] = {h:hdrName, v:hdrValue};
switch (hdrName.toLowerCase())
{
case 'content-encoding': gotContentEncoding = true; break;
case 'content-length' : gotContentLength = true; break;
case 'content-type' : gotContentType = true; break;
case 'date' : gotDate = true; break;
case 'expires' : gotExpiration = true; break;
case 'last-modified' : gotLastModified = true; break;
}
}
}
// try to fill in any missing header information
var val;
val = conn.getContentEncoding();
if (val != null && !gotContentEncoding) this._headers[this._headers.length] = {h:'Content-encoding', v:val};
val = conn.getContentLength();
if (val != -1 && !gotContentLength) this._headers[this._headers.length] = {h:'Content-length', v:val};
val = conn.getContentType();
if (val != null && !gotContentType) this._headers[this._headers.length] = {h:'Content-type', v:val};
val = conn.getDate();
if (val != 0 && !gotDate) this._headers[this._headers.length] = {h:'Date', v:(new Date(val)).toUTCString()};
val = conn.getExpiration();
if (val != 0 && !gotExpiration) this._headers[this._headers.length] = {h:'Expires', v:(new Date(val)).toUTCString()};
val = conn.getLastModified();
if (val != 0 && !gotLastModified) this._headers[this._headers.length] = {h:'Last-modified', v:(new Date(val)).toUTCString()};
// read response data
var reqdata = '';
var stream = conn.getInputStream();
if (stream)
{
var reader = new java.io.BufferedReader(new java.io.InputStreamReader(stream, this._getCharset()));
var line;
while ((line = reader.readLine()) != null)
{
if (this.readyState == 2)
{
this.readyState = 3;
if (this.onreadystatechange)
{
this.onreadystatechange();
}
}
reqdata += line + '\n';
}
reader.close();
this.status = 200;
this.statusText = 'OK';
this.responseText = reqdata;
this.readyState = 4;
if (this.onreadystatechange)
{
this.onreadystatechange();
}
if (this.onload)
{
this.onload();
}
}
else
{
// error
this.status = 404;
this.statusText = 'Not Found';
this.responseText = '';
this.readyState = 4;
if (this.onreadystatechange)
{
this.onreadystatechange();
}
if (this.onerror)
{
this.onerror();
}
}
};
};
}
// ActiveXObject emulation
if (!window.ActiveXObject && window.XMLHttpRequest)
{
window.ActiveXObject = function(type)
{
switch (type.toLowerCase())
{
case 'microsoft.xmlhttp':
case 'msxml2.xmlhttp':
case 'msxml2.xmlhttp.3.0':
case 'msxml2.xmlhttp.4.0':
case 'msxml2.xmlhttp.5.0':
return new XMLHttpRequest();
}
return null;
};
}
//上述代码也是网上广为流传的,请允许我调用,虽然我不知道原作者是谁:P
Step4:
构造表单处理及提交javascript脚本 reg.js
//获取页面指定ID公用函数
function GE(a){return document.getElementById(a);}
//表单检测
function Check(){
//检测ID是否为空
if(GE('regid').value==''){GE('msg').innerHTML='ID不能为空';return false}
//检测PASSWORD是否为空
if(GE('regpassword').value==''){GE('msg').innerHTML='password 不能为空';return false}
//检测OK后提交数据
//建立XMLHttpRequest对象
var X=new XMLHttpRequest();
//检测浏览器是否支持XMLHttpRequest
if(X){
//禁止客户端再次提交表单
GE('regsubmit').disabled=true;
//onreadystatechange为XMLHttpRequest的状态改变的事件触发器
X.onreadystatechange=function(){
//readyState 对象状态
//0 = 未初始化
//1 = 读取中
//2 = 已读取
//3 = 交互中
//4 = 完成
if(X.readyState==4){
//交互完成的处理
//status,服务器返回的状态码, 200为成功
if(X.status==200){
//运行服务器返回的脚本
eval(X.responseText)
}
//服务器端程序运行失败,返回错误代码
else{GE('msg').innerHTML=X.statusText}
}
};
//获取服务器端数据
//open("method","URL"[,asyncFlag])
//请求的目标 URL, 方法
//采用POST为提交数据
//采用true为异步传输, false为同步传输
X.open('POST','reg.asp',true);
X.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
var SendData = 'regid='+GE('regid').value+'®password='+GE('regpassword').value
X.send(SendData)
}
//不支持的话返回错误提示
else{
GE('msg').innerHTML='你的浏览器不支持XMLHttpRequest'
}
}
Step5:
OK,客户端页面全部完成, 重新调整下reg.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>注册</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script type="text/javascript" src="ajax.js"></script>
<script type="text/javascript" src="reg.js"></script>
</head>
<body>
<div id="msg"></div>
ID: <input type="text" id="regid" /><br />
Password: <input type="password" id="regpassword" /><br />
<input type="submit" id="regsubmit" onclick="Check()" />
</body>
</html>
Step6:
构造服务器端程序 reg.asp
<%
dim regid, regpassword, str
regid=Request.Form("regid")
regpassword=Request.Form("regpassword")
if regid="" or regpassword="" then
str = "ID和PASSWORD必须填写"
else
'查询数据库是否存在该ID
'代码略
if rs.EOF then
'不存在则添加数据
'代码略
str = "注册成功,ID为" & regid & " , 密码为" & regpassword
else
str = "注册失败,ID已经存在"
end if
Set rs = nothing
End if
Response.Write "GE('msg').innerHTML='" & str & "';GE('regsubmit').disabled=false"
Response.End
%>
至此,一个简单的注册页面 已经打造成功. 当然,你可以添加更多的代码(比如添加表单内容,扩充表单检测脚本,提高后台程序安全性等)以提高程序实用性

