在看文章前,先指定一个通用的变量xhr,xhr代码ajax对象。
测试浏览器:ie为ie6,firefox为2,其他的未测试。统称ie6为ie,firefox2为ff。
基本的
1,最经典的就是ie下的缓存问题了。
如果使用的是get,那么在ie下出现缓存问题。导致代码只执行一次。解决办法就是加时间戳或者随机数,使url变为唯一,这样就不会出现ie下的缓存问题了,或者改为post提交。
JScript code
-
<!-- Code highlighting produced by Actipro CodeHighlighter (freeware) http://www.CodeHighlighter.com/ -->
xhr.open(
"
get
"
,
"
xxxx.aspx?_dc=
"
+
new
Date().getTime(),
true
);
2,ajax对象属性的大小写问题
在w3c浏览器,如ff中,对大小写是敏感。如
if(xhr.ready
state==4)这种写法,在ie下是成立的,但是在ff下就行不通了,因为ie不区分大小写,ff是区分大小的。
标准写法为if(xhr.ready
State==4),同理还有属性 response
Text,response
XML。
3,ajax状态0问题
有些时候在测试ajax代码的时候,加了 xhr.status==200的判断后,一直不执行xhr.status==200的代码,这个就需要注意了。xhr.status==200是要通过服务器来浏览,并且服务器页面没有发生错误或者转向时才返回200状态的,此状态和你通过浏览器访问页面时服务器定义的状态一致。
直接拖进浏览器浏览结果或者双击运行html页面的,未发生错误时,此时的xhr.status是0,不是200。
所以可以多加一个xhr.status==0的判断。如下
JScript code
-
<!-- Code highlighting produced by Actipro CodeHighlighter (freeware) http://www.CodeHighlighter.com/ -->
if
(xhr.status
==
200
||
xhr.status
==
0
){ alert(
'
ok
'
); }
直接拖进浏览器浏览结果或者双击运行html页面时,又出现一个问题,如果请求的是xml文件,那想当然的是使用responseXML属性返回xmlDom了,但是在ie返回不了xmlDom属性,解决办法如何呢,看下面的responseXML问题。
4,responseXML问题。
要使用responseXML属性,请求的是xml文件或者设置了响应头为"text/xml"的动态页面了。要注意如果请求的是动态页面,一定不要忘记设置contenttype为"text/xml"!!!!!!!!切记~~~~~~
asp为 response.contenttype="text/html"
asp.net为 Response.ContentType="text/html";
php为 header("content-type:text/xml;");
在ie下有个问题,直接拖进浏览器浏览或者双击运行html预览效果时,请求的即使是xml文件,使用responseXML返回不了xmldom。
大家测试下就知道了,如下
showbo.xml
XML code
-
<!-- Code highlighting produced by Actipro CodeHighlighter (freeware) http://www.CodeHighlighter.com/ -->
<?
xml version="1.0" encoding="utf-8"
?>
<
showbo
>
<
item
>
1
</
item
>
<
item
>
2
</
item
>
<
item
>
3
</
item
>
<
item
>
4
</
item
>
</
showbo
>
test.html
JScript code
-
<!-- Code highlighting produced by Actipro CodeHighlighter (freeware) http://www.CodeHighlighter.com/ -->
function
getajax(){
if
(window.XMLHttpRequest)
return
new
XMLHttpRequest();
else
if
(window.ActiveXObject)
return
new
ActiveXObject(
"
microsoft.xmlhttp
"
); }
var
xhr
=
getajax(); xhr.onreadystatechange
=
function
(){
if
(xhr.readyState
==
4
){
if
(xhr.status
==
200
||
xhr.status
==
0
){
var
doc
=
xhr.responseXML,item
=
doc.getElementsByTagName(
"
item
"
); alert(item.length);
//
在ie输出为0,在ff下为4。似乎在ie下未生成xml的树结构,具体原因要问ms了。。
}
else
alert(
'
发生错误\n\n
'
+
xhr.status); } } xhr.open(
"
get
"
,
"
showbo.xml?_dc=
"
+
new
Date().getTime(),
true
); xhr.send(
null
);
解决办法就是使用microsoft.xmldom对象重新建立xml的树结构,如下
JScript code
-
<!-- Code highlighting produced by Actipro CodeHighlighter (freeware) http://www.CodeHighlighter.com/ -->
xhr.onreadystatechange
=
function
(){
if
(xhr.readyState
==
4
){
if
(xhr.status
==
200
||
xhr.status
==
0
){
var
doc
=
xhr.responseXML;
if
(document.all
&&
xhr.status
==
0
){
//
为ie并且直接托进浏览器的时重构xml的树结构
doc
=
new
ActiveXObject(
"
microsoft.xmldom
"
); doc.loadXML(xhr.responseText); doc
=
doc.documentElement; }
var
item
=
doc.getElementsByTagName(
"
item
"
); alert(item.length);
//
在ie输出为0,在ff下为4。似乎在ie下未生成xml的树结构,具体原因要问ms了。。
}
else
alert(
'
发生错误\n\n
'
+
xhr.status); } }
5,为post提交时需要注意的。
1)如果为post提交时,注意要设置
content-type为"application/x-www-form-urlencoded",这样在动态页才可以使用request/request.form/request.querystring对象通过键获取值,否则得使用2进制数据,然后自己分析2进制数据生成字符串对象,使用正则什么的获取对应的值。
2)需要在open以后才能使用xhr.setRequestHeader方法,否则出错。
JScript code
-
<!-- Code highlighting produced by Actipro CodeHighlighter (freeware) http://www.CodeHighlighter.com/ -->
xhr.open(
"
post
"
,
"
xxxx.aspx
"
,
true
); xhr.setRequestHeader(
"
content-type
"
,
"
application/x-www-form-urlencoded
"
);
//
这里。。。。
乱码问题
对于ajax应用来说,乱码也是一个经常出现的问题。
1)meta声明的charset要和请求的页面返回的charset一致。最好在请求的页面中再设置下输出编码。
asp: response.charset="gb2312或者utf-8"
asp.net: response.charset="gb2312或者utf-8"
php: header("charset=gb2312或者utf-8")
2)文件物理存储编码要和meta声明的编码要一致。如meta指定为gb2312,则物理存储编码为ansi。如果为utf-8,则要存储为utf-8编码。
对于asp,如果指定编码为utf-8,记得还要设置
'防止asp使用utf-8编码时中文出现乱码
VBScript code
-
<!-- Code highlighting produced by Actipro CodeHighlighter (freeware) http://www.CodeHighlighter.com/ -->
Session.CodePage
=
65001
Response.CharSet
=
"
utf-8
"
因为asp在国内服务器默认处理编码为gb2312
对于asp.net的话,meta设置为gb2312时,最好设置web.config文件中的
XML code
-
<!-- Code highlighting produced by Actipro CodeHighlighter (freeware) http://www.CodeHighlighter.com/ -->
<
globalization
requestEncoding
="gb2312"
responseEncoding
="gb2312"
/>
,并且在输出中文前设置Response.CharSet="gb2312";
因为asp.net默认的编码为utf-8
3)发送中文到动态页面时使用escape/encodeURI/encodeURIComponent编码一下。建议使用encodeURIComponent。
更多的js编码信息查看这篇文章
JS URL编码函数
对于php来说,还有个问题,需要在服务器点解码下。可以看这篇文章里面的讨论。
写了一个php查询,但是就是传不出中文。
4)如果1-2都对上了但是在接受服务器端发送的信息时还是出现乱码,试试用XML作为信息载体,然后使用responseXML分析下回传的xml文件。因为ajax原本就是用xml作为信息载体的。。。。。。ajax英文名原本就是“异步javascript和xml”【asynchronous javascript and xml】
如果不会解析xml文件,可以参考这篇文章
JavaScript解析XML的方法总结
下面是一些csdn上出现乱码的文章和解决办法,还未解决的看看,是否和你的如出一辙。
在FireFox浏览器中asp.net+AJAX传输的中文字符串到服务器端后乱码的问题!!!!
请教ajax返回乱码
就列上面两个了,要查找更多的,查看这个查询连接,都是ajax出现乱码的问题。
http://so.csdn.net/bbsSearchResult.aspx?q=ajax+%e4%b9%b1%e7%a0%81&p=0
同步问题
问题描述如下,问题来自http://topic.csdn.net/u/20090630/16/d4d07596-65da-430c-8e89-cae60e25e03c.html,精简了下创建ajax的代码
JScript code
-
<!-- Code highlighting produced by Actipro CodeHighlighter (freeware) http://www.CodeHighlighter.com/ -->
function
callServerByPost(url,data,fun) {
var
http_request
=
null
;
if
(window.ActiveXObject)http_request
=
new
ActiveXObject(
"
Microsoft.XMLHTTP
"
); }
else
if
(window.XMLHttpRequest) http_request
=
new
XMLHttpRequest();
if
(
!
http_request) { alert(
'
Giving up :Cannot create an XMLHTTP instance
'
);
return
false
; } http_request.onreadystatechange
=
fun; http_request.open(
"
POST
"
, url,
true
); http_request.setrequestheader(
"
Content-length
"
,data.length); http_request.setRequestHeader(
"
Content-Type
"
,
"
application/x-www-form-urlencoded;charset=UTF-8
"
); http_request.send(data);
//
传送资料
}
function
ajax_post(url,data) { url
=
url
+
"
?t=
"
+
new
Date(); callServerByPost(url,data,
function
fns(){
if
(http_request.readyState
==
4
) {
if
(http_request.status
==
200
) {
return
http_request.responseText;
//
在这里明明调试时http_request.responseText已经有值但是在外边却接收不到
}
else
{ alert(
"
你请求数据有错
"
); } } }); }
function
getData(){
var
url
=
"
ajax_server.aspx
"
;
var
data
=
"
name=ljp&pwd=ljp
"
;
var
t
=
ajax_post(url,data); alert(t);
//
在这里弹出undefined =============================
}
为什么会出现这个问题呢??因为在执行getData中的代码var t=ajax_post(url,data);时,由于指定了异步,所以callServerByPost中的http_request.send(data);//传送资料 这句话并不会中断其他js代码的执行,所以会继续执行getData中的下一句代码,就是alert(t),所以会出现undefined。
其实呢并不仅是ajax异步导致出现undefined的问题。认真看下代码var t=ajax_post(url,data);,t变量是接受的是ajax_post的返回值,但是ajax_post函数中并未使用return 返回任何值,所以默认是返回undefined。
你会说我这里不是使用了return http_request.responseText;//在这里明明调试时http_request.responseText已经有值但是在外边却接收不到返回了吗??????????
大家看清楚了,那个是状态转换函数,你返回任何值是没有意义的,他只是处理ajax的状态,你返回值给谁用的呢?????是不是。
如何解决这个问题呢?一种是改为同步发送,一种就是为异步时使用全局变量来接受ajax的返回值,在状态转换函数中给全局变量赋值。
使用异步+全局变量时要注意的是在ajax未返回前千万不用使用全局变量,要不还是undefined。
下面给出同步的解决办法。异步+全局变量的解决方法看这篇文章
为什么数组作为参数传递进去取不了值出来?
原本最后想放自己写的ajax对象应用池程序的,超过字符限制了,有兴趣可以去下载
下载地址
代码说明这里
<!--End_body//-->