Ajax
Ajax的由来
在早期的前端开发中,用户每次请求都要经过单击-》等待的过程,等待许久,返回的确实请求错误的提示,这无疑让人非常崩溃。
Ajax实际上是"Asynchronous JavaScript and XML"的简写,运用Ajax让无刷新请求页面成为可能。
XMLHttpRequest对象
这是Ajax的核心对象,简称XHR,微软率先提出,后来被众多浏览器厂商实现。Ajax能够以异步的方式对服务器发起请求,页面不需要卸载,通过XHR对象获取数据,然后通过DOM将新数据插入到页面中。
这里应该注意一点,虽然名字中有XML,但Ajax通信与数据格式无关。实际上,这不是一项新技术,只是把几个老技术结合起来而已。
假如你开发的应用只想用在Chrome, IE7+, Opera, Safari上,那么不必大费周章,因为这些浏览器都支持原生XHR。头皮发麻,IE果然是个另类。创建XHR新对象代码如下:
var xhr = new XMLHttpRequest();
那假如我们一定要支持IE7以前的IE浏览器怎么办呢?自讨苦吃?嗯还是得学一下的,因为还是有一部分用户在用古老的IE浏览器。(想起我在某三甲医院看到护士用的系统,winXP,IE5,可怕)
。重点在于我们要让不支持原生XHR的浏览器支持,我们来看看以下代码:
function createXHR(){
//假如存在XHR,那就直接用
if(typeof XMLHttpRequest != "undefined"){
return new XMLHttpRequest();
}else if(typeof ActiveXObject != "undefined"){
if(typeof arguments.callee.activeXString != "string"){
var version = ["MSXML2.XMLHttp.6.0","MSXML2.XMLHttp.3.0","MSXML2.XMLHttp"],
i,
len;
for(i = 0;len=versions.length;i < len;i++){
try{
new ActiveXObject(versions[i]);
arguments.callee.activeXString = version[i];
break;
}catch(e){
//抛出错误
}
}
return new ActiveXObject(arguments.callee.activeXString);
}
}else{
throw new Error("No XHR object available");
}
}
代码执行完毕,就可以创建新的XHR对象了。在以上的函数中,我们先检测浏览器是否对原生XHR支持,如若不支持,则检测ActiveX对象,根据IE中可用的MSXML库的情况创建最新版本的XHR对象。以上内容来自《JavaScript高级程序设计》,由于我生在一个浏览器大一统的时代,兼容性方面考虑不用像以前那样纠结了。
XHR的用法
1、 open(“get/post”,“请求的URI”,“是否异步的布尔值”)
- 在这里要注意,只能向同一个域中使用相同端口和协议的URL发送请求。如果URL与启动请求的页面不一致,将会引发跨域问题。稍后会说明
- open()会启动一个针对某URI的请求,URI相对于当前页面,也可以是绝对路径;调用该方法并不会真正发起请求,而是启动一个请求以备发送。
xhr.open("get","test.json",false);
2、send(“请求主体的参数”)
- 如果不需要传递请求主体参数,必须传递null,因为有些浏览器必须要这个参数。
- 收到响应之后,响应的数据会填充XHR属性,相关属性如下:
属性 | 含义 |
---|---|
responseText | 响应主体文本 |
responseXML | 如果响应类型是"text/xml"或者"application/xml",该属性将保存响应数据的XML DOM文档 |
status | HTTP响应状态码 |
statusText | 状态码原因短语 |
- 根据返回的状态码,判断是否符合要求,并进行下一步操作。不要依赖statusText,因为在跨浏览器用时不可靠
3、 异步请求
异步请求,并不需要等待响应再进行下一步,JS不必等待响应,继续执行。在这段期间,可以检测XHR的readyState属性,表示请求/响应过程的当前活动阶段,如下所示:
- 0:未初始化,尚未调用open()
- 1:启动,已经调用open(),尚未调用send()
- 2:发送,已经调用send(),尚未接受响应
- 3:接收,已经接收到部分响应数据
- 4:完成,已经接收到全部响应数据,可以在客户端使用
我们只对readyState的值为4的阶段感兴趣,因为此时数据已经准备就绪。注意,在调用open()之前,必须指定onreadystatechange事件处理程序才能确保跨浏览器的兼容性。
var xhr = new XMLHttpRequest();
// readyState每次改变,都会触发onreadystatechange事件
xhr.onreadystatechange = function(){
if(xhr.readyState == 4){
if((xhr.status >=200 && xhr.status < 300)||xhr.status==304){
alert(xhr.responseText)
}else{
alert("请求不成功:" + xhr.status);
}
}
}
xhr.open("get","test.json",true);
xhr.send(null);
4、Get请求
//get请求应该在URL后加入参数
function addURLParam(url,key,value){
url += (url.indexOf("?")==-1?"?":"&");
//必须经过encodeURIComponent()编码
url += encodeURIComponent(key) + “=” + encodeURIComoonent(value);
return url;
}
var url = "example.php";
url = addURLParam(url,"name","Mike");
url = addURLParam(url,"age","15");
//初始化请求
xhr.open("get",url,false);
5、Post请求
post的请求主体可以包含非常多的数据,格式不限。默认情况下,服务器对post请求和提交Web表单并不会用同种方式处理,因此服务器端必须有程序来读取发送过来的原始数据并解析。我们可以利用xhr模仿表单提交。
function submit(){
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function(){
if(xhr.readyState == 4){
if((xhr.status) >= 200 && xhr.status < 300) || xhr.status == 304){
alert(xhr.responseText);
}else{
alert(xhr.status);
}
}
};
xhr.open("post","form.java",true);
//把Content-Type的头部信息设置为application/x-www-form-urlencoded
xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
var form = document.getElementById("user-info");
xhr.send(serialize(form));
}