我在开发AJAX过程中遇到的问题及解决方案,分享给大家~ Ajax浏览器IEjQueryDojo
注:这篇文章是很早以前写的了,当时还在上学...当时AJAX刚开始流行,06~07年的时候...当然,现在大家已经用不到这些了,现在有很多的AJAX库把这些都封装好了,例如很早以前的prototype,现在比较流行的Dojo,EXT等,当然,我还是比较喜欢轻量级的jQuery,现在国内出了个 龙博Ajax框架 ,值得关注
先发代码吧~
var request = false; //初始化一个布尔变量,赋值false,由于J_ava_S_cript是弱类型语言,所以后边可以把布尔变量转成其他类型变量
try {
request = new XMLHttpRequest(); //先用普通方式初始化XMLHttpRequest对象,这是AJAX的核心
} catch (trymicrosoft) { //由于IE7以下IE版本(不包括IE7)不支持普通方式初始化XMLHttpRequest对象
try { //所以在普通初始化时会发生异常
request = new ActiveXObject("Msxml2.XMLHTTP"); //所以尝试用IE的方式初始化XMLHttpRequest对象,这是IE5.5及IE6版本的
} catch (othermicrosoft) { //如果还发生异常,说明是IE的更低版本了
try {
request = new ActiveXObject("Microsoft.XMLHTTP"); //这是更低版本的初始化XMLHttpRequest对象的方式
} catch (failed) { //如果还发生异常,说明浏览器不支持XMLHttpRequest对象,这是很老版本的浏览器才会发生的情况
request = false; //让request对象保持布尔变量,并且赋值false
}
}
}
if (!request) //如果request的值还是false,则说明用户的浏览器不支持XMLHttpRequest对象
alert("AJAX初始化错误!"); //提示用户他的浏览器不支持AJAX,在用户访问页面时就提示
//用户他的浏览器不支持AJAX,总比等用户费时费里填完表单
//在用户提交时再提示用户不支持效果要好,这样也许等用户
//换了浏览器了还会来访问网站,如果是提交时才提示,用户
//肯定很郁闷,估计就不会再来访问你的网站了,所以把
//初始化XMLHTTPRequest对象的代码放在方法外,在载入
//页面时就初始化是必要的,当然也可以写到方法里在页面
//载入时调用初始化方法,至于用什么方式那看程序员的习惯了
function checkUserId(userId) { //这是运行AJAX的方法,用来检测这个用户名是否被注册
var url = "servlets/CheckUserId?userId="+userId; //这是AJAX向服务器发送请求的连接,指定向服务器哪个页面发送请求,以及要传
//给服务器的值,这里是一个servlet
request.open("GET", url, true); //打开连接,就像比赛时的"预备",此时没有向服务器发送任何数据
request.onreadystatechange = updatePage; //指定服务器处理完请求后调用的方法,此方法用来改变页面里的某些东西,以体现出
//"无刷新"的效果,就像是在本地运行的程序一样
request.send(null); //向服务器发送请求,此时才向服务器发送数据,send是以POST方式发送请求时才放数据进去,此处用的是GET
//方式,所以里边参数为null
}
function updatePage() { //这是刚才指定的服务器处理完请求后的回调方法
if (request.readyState == 4){ //判断HTTP就绪状态,因为状态每改变一次就会调用一次方法,而就绪状态有5种,分别是
//0:请求没有发出(在调用 open() 之前)。
//1:请求已经建立但还没有发出(调用 send() 之前)。
//2:请求已经发出正在处理之中(这里通常可以从响应得到内容头部)。
//3:请求已经处理,响应中通常有部分数据可用,但是服务器还没有完成响应。
//4:响应已完成,可以访问服务器响应并使用它。
//所以要当响应完成时才执行页面更新
if (request.status == 200){ //检查HTTP状态码,等于200时说明服务器正常处理完数据,404是找不到页面,500是服务器运行错误,其他
//的状态码请查阅相关资料
if(request.responseText=="true"){ //responseText属性包含的是服务器返回的信息,这里我只返回了true或false
document.getElementById("info1").innerHTML ="用户名符合要求,请继续!"; //如果服务器返回的是trun,说明可以用这个ID注册
document.getElementById("info1").className = 'true'; //这是改变DIV的CLASS,也就是改变DIV的样式
}else{ //由于只返回了2个值,所以不是true那当然是false了,说明不能用这个ID注册
document.getElementById("info1").innerHTML ="用户名已存在,请重新输入!";
document.getElementById("info1").className = 'fall';
}
}else if (request.status == 404){ //如果HTTP状态码是404,说明要发送请求的页面不存在
alert("Request URL does not exist");
}
else{ //如果是其他的状态码,就不做处理了,直接提示状态码,这个一般是给程序员调试时看的,正常情况下用户是不会看到这个提示的
alert("Error: status code is " + request.status);
}
}
}
页面里是这样的,这里只给出调用AJAX的HTML标签
又是5Q的字符串过滤问题,NND,我把会被过滤的字符串中间加了个下划线,代码里没有的
<in_put ty_pe="text" on_Focus="checkUserId(this.value);">
好了,介绍完我的代码了,该说说我遇到的问题了:
例如我用"lele"作为用户名注册成功了,当我返回注册页面时,在用户名那输入"lele",还是提示这个用户名可以注册,怎么刷新都没用,除非把浏览器窗口关掉,服务器重起都没用,这是什么问题呢?经过仔细研究,发现是浏览器缓存的问题,由于注册成功后返回注册页面,还是那个浏览器窗口,传的参数也一样,所以浏览器根本没有向服务器发送请求而是用了缓存里注册前检测到的结果
所以要解决这个问题,我在代码里加了点东西,下面给出完整代码,新加的代码用蓝色表示:
var request = false; //初始化一个布尔变量,赋值false,由于J_ava_S_cript是弱类型语言,所以后边可以把布尔变量转成其他类型变量
try {
request = new XMLHttpRequest(); //先用普通方式初始化XMLHttpRequest对象,这是AJAX的核心
} catch (trymicrosoft) { //由于IE7以下IE版本(不包括IE7)不支持普通方式初始化XMLHttpRequest对象
try { //所以在普通初始化时会发生异常
request = new ActiveXObject("Msxml2.XMLHTTP"); //所以尝试用IE的方式初始化XMLHttpRequest对象,这是IE5.5及IE6版本的
} catch (othermicrosoft) { //如果还发生异常,说明是IE的更低版本了
try {
request = new ActiveXObject("Microsoft.XMLHTTP"); //这是更低版本的初始化XMLHttpRequest对象的方式
} catch (failed) { //如果还发生异常,说明浏览器不支持XMLHttpRequest对象,这是很老版本的浏览器才会发生的情况
request = false; //让request对象保持布尔变量,并且赋值false
}
}
}
if (!request) //如果request的值还是false,则说明用户的浏览器不支持XMLHttpRequest对象
alert("AJAX初始化错误!"); //提示用户他的浏览器不支持AJAX
function checkUserId(userId) { //这是运行AJAX的方法,用来检测这个用户名是否被注册
var thisDate=new Date(); //初始化一个时间对象,大家应该想到我要做什么了,对的,就是每次发送请求时都传一个不同的数据过去
//这样浏览器就不会去调用缓存里的数据了,而这个数据服务器不用去获取处理,也就是说服务器端代码不用
//做任何改变
var thisTime=thisDate.getHours()+thisDate.getMinutes()+thisDate.getSeconds(); //这个字符串是"时.分,秒"的组合,这样24小时才
//有一次几率传的参数一样,我不相信谁会24小时不关一次页面,就算他不关,也没那么好的运气会时分秒一样时去检测用户名,除非有人
//蓄意搞破坏
var url = "servlets/CheckUserId?userId="+userId+"&time="+thisTime; //这是AJAX向服务器发送请求的连接,指定向服务器哪个页面发送请求,以及要传
//给服务器的值,这里是一个servlet
request.open("GET", url, true); //打开连接,就像比赛时的"预备",此时没有向服务器发送任何数据
request.onreadystatechange = updatePage; //指定服务器处理完请求后调用的方法,此方法用来改变页面里的某些东西,以体现出
//"无刷新"的效果,就像是在本地运行的程序一样
request.send(null); //向服务器发送请求,此时才向服务器发送数据,send是以POST方式发送请求时才放数据进去,此处用的是GET
//方式,所以里边参数为null
}
function updatePage() { //这是刚才指定的服务器处理完请求后的回调方法
if (request.readyState == 4){ //判断HTTP就绪状态,因为状态每改变一次就会调用一次方法,而就绪状态有5种,分别是
//0:请求没有发出(在调用 open() 之前)。
//1:请求已经建立但还没有发出(调用 send() 之前)。
//2:请求已经发出正在处理之中(这里通常可以从响应得到内容头部)。
//3:请求已经处理,响应中通常有部分数据可用,但是服务器还没有完成响应。
//4:响应已完成,可以访问服务器响应并使用它。
//所以要当响应完成时才执行页面更新
if (request.status == 200){ //检查HTTP状态码,等于200时说明服务器正常处理完数据,404是找不到页面,500是服务器运行错误,其他
//的状态码请查阅相关资料
if(request.responseText=="true"){ //responseText属性包含的是服务器返回的信息,这里我只返回了true或false
document.getElementById("info1").innerHTML ="用户名符合要求,请继续!"; //如果服务器返回的是trun,说明可以用这个ID注册
document.getElementById("info1").className = 'true'; //这是改变DIV的CLASS,也就是改变DIV的样式
}else{ //由于只返回了2个值,所以不是true那当然是false了,说明不能用这个ID注册
document.getElementById("info1").innerHTML ="用户名已存在,请重新输入!";
document.getElementById("info1").className = 'fall';
}
}else if (request.status == 404){ //如果HTTP状态码是404,说明要发送请求的页面不存在
alert("Request URL does not exist");
}
else{ //如果是其他的状态码,就不做处理了,直接提示状态码,这个一般是给程序员调试时看的,正常情况下用户是不会看到这个提示的
alert("Error: status code is " + request.status);
}
}
}
这样问题就解决了,HTML部分不用改动
当然,解决方法不只我这一种,大家应该想到了其他的解决方法,我只是给大家提供一个思路~