"Ajax" came into my world !(一)
时间:2010-09-08 来源:花吻道
"Ajax" came into my world!
1、Ajax是什么?
AJAX全称是 Asynchronous JavaScript and XML,Ajax是一种由现有技术组合的技术,具体由
(1) 语义化html标记、(2)文档对象模型(DOM)、(3) javascript、(4) XML
4个部分组成。
2、Ajax的原理是什么?
ajax的原理是使用Javascript的XMLHTTPRequest对象和服务器进行通信,基于这种技术,Javascript
可在不重载页面的情况下与web服务器进行数据交互,然后通过Javascript操作 DOM更新数据。
3、XMLHttpRequest 对象
XMLHttpRequest 是Ajax的核心对象,也是Ajax技术应用的基础,所有的浏览器厂商都实现了具有相
同功能的XMLHttpRequest对象,不过,不同的浏览器间创建XMLHttpRequest对象会存在差异,微软从
ie5以ActiveX插件的形式已经可以进行Ajax应用的开发了。
(*)使用ActiveX插件必须使用Microsoft.XMLHTTP ActiveX组件来实例化MLHttpRequest 对象
var xhr = new ActiveXObject("Microsoft.XMLHTTP");
(*)微软从ie7开始添加了对xmlhttp原生的支持,除ie5,和ie6以外的浏览器则使用名 XMLHttpRequest 的javascript内建对象
var xhr = new XMLHttpRequest();
每个js类库创建XMLHttpRequest对象的方法
Jquery library 提供的创建XHR对象方法
xhr: window.XMLHttpRequest && (window.location.protocol !== "file:" || !window.ActiveXObject) ?
function() {
return new window.XMLHttpRequest();
} :
function() {
try {
return new window.ActiveXObject("Microsoft.XMLHTTP");
} catch(e) {}
}
window.location.protocol 这个属性是得到当前的网络通信协议 如"http:" 或 "file:" 等;
在IE7浏览器下网络通讯协议为 file 的时候不能用 window.XMLHttpRequest
jquery在创建代码里做了判断 (window.location.protocol === "file:")
YUI2.8.1中connection的创建方式
createXhrObject:function(transactionId)
{
var obj,http,i;
try
{
http = new XMLHttpRequest();
obj = { conn:http, tId:transactionId, xhr: true };
}
catch(e)
{
for(i=0; i<this._msxml_progid.length; ++i){
try
{
http = new ActiveXObject(this._msxml_progid[i]);
obj = { conn:http, tId:transactionId, xhr: true };
break;
}
catch(e1){}
}
}
finally
{
return obj;
}
}
YUI创建XHR对象的函数,进行了简单的包装,除去没有protocol的判断,其他略有不同的是提供了_msxml_progid 静态数组
提供了3种progid不同的 ActiveXObject 对象
'Microsoft.XMLHTTP',
'MSXML2.XMLHTTP.3.0',
'MSXML2.XMLHTTP'
]
yui 3.1
function _xhr() {
return w.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject('Microsoft.XMLHTTP');
}
在3.1中去除了 _msxml_progid ,直接是使用 Microsoft.XMLHTTP
DoJo
d._xhrObj = function(){
var http, last_e;
if(!dojo.isIE || !dojo.config.ieForceActiveXXhr){
try{ http = new XMLHttpRequest(); }catch(e){}
}
if(!http){
for(var i=0; i<3; ++i){
var progid = d._XMLHTTP_PROGIDS[i];
try{
http = new ActiveXObject(progid);
}catch(e){
last_e = e;
}
if(http){
d._XMLHTTP_PROGIDS = [progid];
break;
}
}
}
if(!http){
throw new Error("XMLHTTP not available: "+last_e);
}
return http;
}
Dojo和 YUI2.8.1类似 提供了_XMLHTTP_PROGIDS,多个版本的ActiveXObject
Microsoft.XMLHTTP 和 Msxml2.XMLHTTP 的区别
前缀是Microsoft命运的是低版本的,一般是msxml2.6以下版本使用,Msxml2则是高版本的,受msxml3.dll+支持
4、学会了创建XHR对象,写一个简单的请求
var win = window,
callback = function(){},
xhr = (win.XMLHttpRequest ? function(){
return new XMLHttpRequest();
} : function(){
return new ActiveXObject('Microsoft.XMLHTTP');
})();
if(xhr){
xhr.onreadystatechange = callback;
xhr.open('GET','http://www.baidu.com/?',true);
xhr.send(null);
}
onreadystatechange属性指定了回调方法,在请求的不同阶段被调用了几次,可以通过readyState属性进行交互
readyState各个状态下整数值
0:尚未初始化
1:载入中
2:载入完成
3:交互
4:完成
在callback中进行测试,在整数值为 1-4 时会运行callback.
还有一些xhr对象的属性:
xhr.responseText 在响应中返回的数据字符串表示
xhr.responseXML 是一个兼容DOM核心的文档对象
xhr.status 是一个表示请求状态的数字代码,如 200表示"ok",404表示"Not Found";
使用onreadystatechange属性的方法和其他属性就能很容易判断请求的状态是否成功
提到了onreadystatechange,在 YUI 2X的 ajax方法中 并没有采用原生支持的onreadystatechange属性,
代替的方案则是利用定时器轮训去检测xhr的状态
handleReadyState函数中
this._poll[o.tId] = window.setInterval(
function(){
if(o.conn && o.conn.readyState === 4){
}
}
,this._polling_interval);
用window.setInterval去轮训的方式, 在YUI3中已经被废除了,依然改换成原生的onreadystatechange
一些公用的XMLHttpRequest 方法:
open() 用户指定请求的 url,方法,以及请求相关的其他可选属性
setRequestHeader(label,value) 用于以给定的label和value,为请求应用一个头部信息。
该方法必须在请求的open()方法之后且在send()方法之前调用
send(content) 用于发送请求,可以包含可选的内容,例如post请求的内容
abort 用于停止当前的请求
getAllResponseHeaders() 返回字符串形式的完整的头部信息集合
getResponseHeader(label)返回指定头部的一个单独的字符串值
5、cache缓存问题
由于缓存机制,每次通过XMLHttpRequest获取的内容总是首次访问的数据.
可以加入时间戳解决
url = "http://www.cnblog.com/windows7/?t" + new Date().getTime();
也可以加入随机数解决
。。。。各种玩耍 0 0
6、编码问题
通过XMLHttpRequest获取的数据和通过XMLHttpRequest POST发送的数据,默认的字符编码是 utf-8
7、JSONP
JSONP是一个非官方的协议,它允许在服务器端集成Script tags返回至客户端,通过javascript callback的形式实现跨域访问(这仅仅是JSONP简单的实现形式)。
我们看下jquery 是如何实现 JSONP的
$.ajax({
dataType: 'jsonp',
data: 'id=10',
jsonp: 'jsonp_callback',
url: 'http://www.baidu.com/,
success: function () {
},
});
当检测到是jsonp时,会自动在url后加入callback = jsonp_callback+时间戳的形式
如 url = 'http://www.baidu.com/',则会形成 'http://www.baidu.com/?callback=jsonp_callback1989823112';
然后创建一个名为 window["jsonp_callback1989823112"] 的全局函数
window[ jsonp ] = window[ jsonp ] || function( tmp ) {
data = tmp;
success();
complete();
// Garbage collect
window[ jsonp ] = undefined;
try {
delete window[ jsonp ];
} catch(e) {}
if ( head ) {
head.removeChild( script );
}
};
从服务端返回的正常调用方式为
jsonp1283891442859([{..}]);
因jsonp1283891442859其为全局变量所以直接能调用
8、如何判断XHR请求是否成功
拿jquery举例,httpSuccess方法
return !xhr.status && location.protocol === "file:" ||
( xhr.status >= 200 && xhr.status < 300 ) ||
xhr.status === 304 || xhr.status === 1223 || xhr.status === 0;
不仅判断了 status >=200 且 status < 300,
在ie浏览器下有时候会返回1223状态码,其实是状态204 ,opera下返回0代表返回304
9、YUI3的IO中 增加了对 "PUT"请求的处理, jquery.1.4.2 中还有 "DELETE",
PUT 代表 "添加资源",DELETE 代表 "请求删除资源";
Web服务器默认的只支持Post和Get这两种只读的请求方法,但是随着Ajax XMLHttpRequest 和 REST风格应用的深入,http 1.1协议还支持如下请求方法:
OPTIONS, HEAD, DELETE,PUT,TRACE, CONNECT.
这两个方法的功能完全可以用post和get取代