ajax是一种在无需重新加载整个网页的情况下,能够更新部分网页的技术
1.XMLHttpRequest(可扩展超文本传输请求)对象
XMLHttpRequest是一种支持异步请求的技术,它是Ajax的核心
可以向服务器提出请求并处理响应,而不阻塞用户;可以在页面加载以后进行页面的局部更新
要完整实现一个AJAX异步调用和局部刷新,通常需要以下几个步骤:
- 创建XMLHttpRequest对象,也就是创建一个异步调用对象;
- 创建一个新的HTTP请求,并指定该HTTP请求的方法、URL;
- 设置响应HTTP请求状态变化的函数(服务器响应)
- 发送HTTP请求
- 获取异步调用返回的数据
- 使用JavaScript和DOM实现局部刷新
2.创建XMLHttpRequest对象
//封装通用的xhr对象创建函数,兼容各个版本
function createXHR(){
//判断浏览器是否将XMLHttpRequest对象作为本地对象实现,针对IE7,firefox,opera等
if(typeof XMLHttpRequest != "undefined"){//也可以写为if(window.XMLHttpRequest)
return new XMLHttpRequest();
}else if(typeof ActiveXObject != "undefined"){//针对老版本IE浏览器(IE5/6),也可以写为if(window.ActiveXObject)
//将所有可能出现的ActiveXObject版本放在一个数组中
var xhrArr = ['Microsoft.XMLHTTP','MSXML2.XMLHTTP.6.0','MSXML2.XMLHTTP.5.0','MSXML2.XMLHTTP.4.0','MSXML2.XMLHTTP.3.0','MSXML2.XMLHTTP.2.0',]
//遍历创建XMLHttpRequest(ActiveXObject)对象
var len = xhrArr.length,xhr=null;
for(var i = 0;i<len;i++){
try{//创建XMLHttpRequest(ActiveXObject)对象,需要输入版本号进行尝试
xhr = new ActiveXObject(xhrArr[i]);
break;//如果创建成果就退出循环
}
catch(ex){//如果抛出问题则...
}
}
return xhr;
}else{//如果以上都不支持就抛出错误信息
throw new Error('No XHR object availabel.')
}
}
3.open方法–建立请求
语法:open(method,url,async)
功能:创建HTTP请求,规定请求的类型、URL及是否异步处理请求
method:请求类型,GET(默认)或POST
与POST相比,GET更简单也更快,并且在大部分情况下都能用,但在以下情况中,必须使用POST请求:
- 无法使用缓存文件(更新服务器上的文件或数据库时)
- 向服务器发送大量数据(POST没有数据量限制)
- 发送包含未知字符的用户输入时,POST比GET更稳定也更可靠
url:文件在服务器上的位置
url参数是open()方法中唯一一个必须要指定的参数,用来设置服务器上文件的地址,该文件可以是任何类型的文件,如.txt和.xml,或者服务器脚本文件,如.asp和.php(在传回响应之前,能够在服务器上执行任务)
async:true(异步)或false(同步)
- 同步:提交请求->等待服务器处理->处理完毕返回 在此期间客户端浏览器不能干任何事
- 异步:请求通过事件触发->服务器处理(这时浏览器仍然可以做其它事情)->处理完毕
async是一个布尔值,默认为true(异步),客户机不用等待服务器响应;如果设置为false(同步),客户机就要等到服务器返回消息后才去执行其它操作
XMLHttpRequest 对象如果要用于 AJAX 的话,其open()方法的sync参数必须设置为 true
注意:open方法不会向服务器发送真正请求,它相当于初始化请求并准备发送,它只能向同一个域中使用相同协议和端口的URL发送请求,否则会因为安全原因报错
var xhr = createXHR();
//创建请求
xhr.open('get','./ys/add_vhost.php',true);
4.设置状态请求变化函数与send
//响应XMLHttpRequest对象状态变化的函数,onreadystatechange在readyState属性发生改变时触发
xhr.onreadystatechange = function(){
//异步调用成功,响应内容解析完成,可以在客户端调用
if(xhr.readyState == 4){
if((xhr.status >=200 && xhr.status<300) || xhr.status ===304){
//status大于等于200小于300真正表示异步调用完全成功;304表示请求资源没有被修改,可以使用浏览器缓存,也就是上一次调用成功
// 获得服务器返回的数据,存在add_vhost.php内
}
}
}
send方法
语法:send(string)
功能:将请求发送到服务器
参数说明:string仅用于post请求
注意:仅在POST请求时可以传入参数,不需要则发送null,在调用send方法之后请求真正被发往服务器(但在GET)
使用POST需要设置头部信息
- 如果需要像HTML表单那样POST数据,需使用setRequestHeader()来添加HTTP头,然后在send()方法中规定希望发送的数据
- 语法:XHR对象.setRequestHeader(header,value);
xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded");//写死
如果需要向服务器传参
- 使用get方法时将参数写在url地址末尾以?开头,多个参数中间用&分隔
xhr.open('get','./ys/add_vhost.php?user=zhangsan&id=12345',true);
xhr.send(null);
- 使用post方法时,需要先添加HTTP头部,再在send中以对象形式传入参数(不允许写在url中)
xhr.open('post','./ys/add_vhost.php',true);
xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded");
xhr.send({user:"zhangsan",id:12345});
5.获取异步调用返回的数据–在函数内部写
在收到响应后响应数据会填充到XHR对象的属性中,常用的有以下4个:
- responseText --从服务器进程返回数据的字符串形式,只有当 readyState属性值变为4时,responseText属性才可用,因为这表明AJAX请求已经结束!
- responseXML --从服务器进程返回的DOM兼容的文档数据对象
- status --从服务器返回的数字代码,如404(未找到)和200(已就绪)
- status Text --伴随状态码的字符串信息
//响应XMLHttpRequest对象状态变化的函数,onreadystatechange在readyState属性发生改变时触发
xhr.onreadystatechange = function(){
//异步调用成功,响应内容解析完成,可以在客户端调用
if(xhr.readyState == 4){
if((xhr.status >=200 && xhr.status<300) || xhr.status ===304){
//status大于等于200小于300真正表示异步调用完全成功;304表示请求资源没有被修改,可以使用浏览器缓存,也就是上一次调用成功
// 获得服务器返回的数据,即add_vhost.php内的数据
console.log(xhr.responseText);//打印获取数据
}
}
}
//请求 cd_catalog.xml 文件,并解析响应
xmlDoc=xmlhttp.responseXML;//XML格式对应.xml文件
txt="";
x=xmlDoc.getElementsByTagName("ARTIST");
for (i=0;i<x.length;i++)
{
txt=txt + x[i].childNodes[0].nodeValue + "<br>";
}
document.getElementById("myDiv").innerHTML=txt;
6.json
JSON全称是javascript对象表示法,它是一种数据交换的文本格式(只是一种格式!),不是一种编程语言,用于读取结构化数据,目的是取代繁琐笨重的XML格式
语法规则
- 简单值
简单值使用与JS相同的语法,可以在JSON中表示字符串、数值、布尔值和null
字符串必须使用双引号表示,不能用单引号,数值必须以十进制表示,且不能是NaN和Infinity
JSON不支持JS中的特殊值undefined - 对象
对象作为一种复杂数据类型,表示的是一组有序的键值对,每个键值对中的值可以是简单值,也可以是复杂数据类型的值
JSON中对象的键名必须放在双引号内,因为JSON不是JS语句,所有没有末尾的分号
同一个对象中不应该出现两个同名属性(键名不能重复) - 数组
数组也是一种复杂数据类型,表示一组有序的值得列表,可以通过数值索引来访问其中的值
数组或对象最后一个成员的后面,不能加逗号
{
"code": 0,
"slider": [
{
"linkUrl": "https://m.imooc.com/act/share",
"picUrl": "img/fm1.jpg"
},
{
"linkUrl": "https://m.imooc.com/act/share",
"picUrl": "img/fm2.jpg"
},
{
"linkUrl": "https://m.imooc.com/act/share",
"picUrl": "img/fm3.jpg"
},
{
"linkUrl": "https://m.imooc.com/act/share",
"picUrl": "img/fm4.jpg"
},
{
"linkUrl": "https://m.imooc.com/act/share",
"picUrl": "img/fm5.jpg"
},
{
"linkUrl": "https://m.imooc.com/act/share",
"picUrl": "img/fm6.jpg"
}
]
}
JSON对象的两个方法:
- parse()
语法:JSON.parse()
功能:用于将JSON字符串转化成对象 - stringify()
语法:JSON.stringify()
功能:用于将一个值转为字符串,该字符串符合JSON格式,并且可以被JSON.parse()方法还原
var data = null;
data = JSON.parse(xhr.responseText);//将字符串转换为JS对象
JSON总结
- JSON之所以流行,是因为可以把JSON数据结构解析为有用的JS对象
- JSON对象的stringify()和parse()方法可以分别用于把JS对象序列化为JSON字符串和把JSON字符串解析为原生JS值
- JS的eval()类似于JSON.parse()方法,可以将JSON字符串转换为JS对象,但是eval()可以执行不符合JSON格式的代码,有可能会包含恶意代码,建议少用
补充:
eval()方法
eval()函数可以将字符串解析为JS代码执行
语法:eval(string) 参数string是必须的,其中包含要执行的JS代码
eval("m=10;n=20;document.write(n-m)");
eval()方法把上面的字符串作为一段js代码执行,所以页面中会输出n-m的结果
eval("alert('hello')");
页面弹窗
在读取JSON数据时,不建议使用eval()
each方法
jQuery.each()函数用于遍历指定的对象和数组,也可以写为$.each()
语法: $.each(object,function(index,value){})
object指定需要遍历的数据
function指定用于循环执行的函数,其中
index表示数组索引或对象属性名
value表示数组项或对象属性值
遍历的数据通常是数组,json,DOM等
var arr = [6,7,8];
$.each(arr,function(index,value){
console.log('index:'+index+',value:'+value);
})//index:0,value:6...
遍历对象
var obj = {
name:'xm',
age:20,
sex:'male'
}
$.each(obj,function(index,value){
console.log(index+':'+value);
});//name:xm...
7.渲染数据
function renderDataToDom(){
var img = data.slider,i,len = img.length,
str = "",banner = document.getElementById("banner");
for(i=0;i<len;i++){
str += '<a href="'+img[i].linkUrl+'"><img src="'+img[i].picUrl+'"></a>';
}//通过循环将slider里的内容加入str
banner.innerHTML = str;
}
最终程序
function createXHR() {
//判断浏览器是否将XMLHttpRequest作为本地对象实现,针对IE7,Firefox,Opera等浏览器
if (typeof XMLHttpRequest != "undefined") {
return new XMLHttpRequest();
} else if (typeof ActiveXObject != "undefined") {
//将所有可能出现的ActiveXObject版本放在一个数组中
var xhrArr = ['Microsoft.XMLHTTP', 'MSXML2.XMLHTTP.6.0', 'MSXML2.XMLHTTP.5.0', 'MSXML2.XMLHTTP.4.0', 'MSXML2.XMLHTTP.3.0', 'MSXML2.XMLHTTP'];
//遍历创建XMLHttpRequest对象
var len = xhrArr.length;
for (var i = 0; i < len; i++) {
try {
//创建XMLHttpRequest对象
xhr = new ActiveXObject(xhrArr[i]);
//如果创建XMLHttpRequest对象成功,则跳出循环
break;
} catch (ex) {}
}
} else {
throw new Error("No XHR object available.");
}
}
var xhr = createXHR(),
data = null; //用于接收服务器端返回的数据
//响应XMLHttpRequest对象状态变化的函数
xhr.onreadystatechange = function() {
//异步调用成功
if (xhr.readyState === 4) {
if ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304) {
//获得服务器返回的数据
data = JSON.parse(xhr.responseText);
// 渲染数据
renderDataToDom();
} else {
console.log('unsuccess');
}
}
};
//创建http请求
xhr.open('get', './server/slider.json', false);
//发送http请求
xhr.send(null);
// 渲染数据
function renderDataToDom() {
var img = data.slider,
i,
len = img.length,
str = "",
banner = document.getElementById("banner");
// 遍历数据,拼接字符串
for (i = 0; i < len; i++) {
str += '<a href="' + img[i].linkUrl + '"><img src="' + img[i].picUrl + '"></a>'
}
// 渲染图片信息
banner.innerHTML = str;
}