封装Ajax框架!(前言篇)
Ajax技术就是利用javascript和xml实现异步交互的功能。
首先先来介绍一下Ajax相关知识点,如果这些你都会的话,请直接跳转到封装ajax框架!(代码篇)
一、Ajax对象的创建
1、创建Ajax对象的方式
a、第一种方式是针对IE浏览器
b、第二种方式针对w3c:在IE的高版本(IE8+),已经支持了XMLHttpRequest类
2、解决兼容性
a、创建公共文件 public.js
b、在需要使用ajax对象的页面中,包含以上js文件
二、ajax对象的相关属性和方法
方法:
1、初始化ajax对象 open(method,url)
method:请求方式 get、post
url:请求地址
2、设置请求头信息 setRequestHeader(header,value)
header:请求头的名称
value:请求头的信息
3、开始发送请求 send(content)
只有当ajax对象的send方法被调用时,才会发送请求
content :post请求时所传递的数据,get请求时这里直接设置为null
属性:
1、当ajax对象状态码发生改变时所触发的回调函数:onreadystatechange
它的值是一个函数首地址(匿名函数)
xhr.onreadystatechange = function(){}
2、ajax对象的状态码(一个数字,从0-4): readyState
3、ajax对象接收到的响应状态码(常用)(200、302、404):status
4、ajax对象接收到的http响应状态文本(不常用):statusText
5、ajax对象接收到http响应主体字符串(text/html):responseText
6、ajax对象接收到的http响应主体内容(text/xml):responseXML
三、发送GET请求
1、 向服务器发送用户名,并返回hello,zhangsan
php代码如下:
return:返回,将结果返回给php程序本身
echo:输出,利用http协议将数据响应给客户端
上面代码不足之处:
a、如果将请求地址改为一个不存在的页面地址,那么服务器仍然会返回一个错误信息,而我们的程序应该在得到一个正确的返回结果后才去对数据进行处理。
2、解决IE缓存问题(将服务器端的PHP略做修改)
在IE下,仍然输出hello,zhangsan、其他浏览器中是正常输出
原因:在IE中,默认有缓存功能,将每次获取的php文件的输出结果缓存下来,下次ajax对象请求时,如果在缓存目录下,找到对应缓存文件,就直接使用缓存文件。
解决方式:
a、在url后面加随机数:Math,random( );
var URL = "demo.php?name=zhangsan&n="+Math.random();
b、在url后面加(毫秒)时间戳:new Date().getTime();
var URL = "demo.php?name=lisi&n="+new Date().getTime();
以上两种方法确保每次请求的url是唯一的。
c、设置ajax对象的请求头,if-modified-since,强制让ajax对象发送请求。
0:表示文件最后修改时间会和服务器上这个资源文件最后修改时间进行比较,肯定是不同的,所以服务器返回了最新数据
xhr.setRequestHeader("If-Modified-Since","0");
以上三种方式并没有根本上解决缓存问题,前两种方式更是缓存下来N个文件。
d、设置http响应头中的cache-control选项,告诉浏览器不要缓存,必须每次重新请求
实例:检查用户名是否可用
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>检查用户名是否存在</title> 6 <script src="jquery-1.12.4.min.js"></script> 7 <script src="public.js"></script> 8 <script> 9 $(function(){ 10 //创建ajax对象,此时状态码为0 11 var xhr =creatxhr(); 12 $("#name").blur(function () { 13 var name = $(this).val(); 14 //方法1:随机数 15 var URL = "demo.php?name="+name+"&n="+new Date().getTime(); 16 //初始化ajax对象 此时状态码为1 17 xhr.open("get",URL); 18 //ajax对象状态码发生改变时所触发的回调函数 19 xhr.onreadystatechange = function(){ 20 //状态码为4说明接收完毕,做进一步的处理 21 if(xhr.readyState == 4 && xhr.status == 200){ 22 if(xhr.responseText == 1){ 23 $(".error").html("用户名已存在").css({display:"inline-block",color:"red"}); 24 }else{ 25 $(".error").css({display:"none"}); 26 return false; 27 } 28 } 29 }; 30 //发送请求,此时状态码为2 31 xhr.send(null); 32 }); 33 34 }) 35 </script> 36 </head> 37 <body> 38 <form> 39 <div class="form-group"> 40 <label for="name">用户名:</label> 41 <span class="error"></span> 42 <input type="text" id="name" placeholder="请输入用户名"> 43 </div> 44 </form> 45 </body> 46 </html>
1 /** 2 * Created by 123 on 2017/7/30. 3 */ 4 //第一种创建ajax对象 5 function creatxhr(){ 6 var xhr; 7 var str = window.navigator.userAgent; 8 //判断是否为IE浏览器,如果是创建相应的ajax对象 9 if(str.indexOf("MSIE") >0){ 10 xhr = new ActiveXObject(); 11 }else{ 12 xhr = new XMLHttpRequest(); 13 } 14 return xhr; 15 } 16 //另外一种创建ajax对象 17 function creatxhr1(){ 18 try{return new ActiveXObject();}catch(e){} 19 try{ 20 return new XMLHttpRequest(); 21 }catch(e){ 22 alert("请更换浏览器!"); 23 } 24 }
1 <?php 2 //禁止客户端缓存数据 3 header("Cache-Control:no-cache,must-revalidate"); 4 $name = $_GET['name']; 5 //连接数据库服务器、选择数据库 6 mysql_connect("localhost","root","111111"); 7 mysql_select_db("shop"); 8 mysql_query("set names gb2312"); 9 //sql语句 10 $sql = "select * from users where username = '$name'"; 11 $result =mysql_query($sql); 12 $num = mysql_num_rows($result); 13 $num大于表示表中已经存在一条记录 14 mysql_close(); 15 //根据结果集总行数返回0或1.0表示用户名不存在,1表示用户名已存在 16 if($num > 0){ 17 echo 1; 18 }else{ 19 echo 0; 20 } 21 ?>
四、发送post请求
1、get和post的区别
a、get请求将参数放到请求地址url的后面
b、post请求时将参数放在http请求空白行的后面
c、get请求时参数大小有限制
d、post请求理论上对参数大小无限制
e、postt比get安全一些
2、其他不同
post请求时,除了参数格式不同之处,还比get请求多了一个Content-Type的请求头,它的值是application-form-urlencoded,表示本次提交的数据是字符数据,同时post还可以同时提交二进制数据和字符数据,如:multipart/form-data
ajax发送请求其实就是模拟http请求
ajax对象的post请求也要加上content-type的请求头
3、代码
a、xhr.open("post","demo.php") post请求 demo.php后面没有参数
b、xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded")
设置请求头信息:
content-type:传递数据的数据类型
application/x-www-form-urlencoded:表示数据是字符数据
c、xhr.send(data);data:会自动将参数放到请求空白行的后面
4、计算两个数的四则运算
如果想做四则运算的话,上面的代码稍微修改下:
如果需要从服务器返回多个结果,可以将结果拼接一个字符串,使用一个指定的分隔符,如:"|",在客户端程序中,再将字符串按照分隔符进行分割。
5、文件上传
以post形式提交数据:method=post
指定提交的数据可以是二进制数据或字符数据:enctype="multipart/form-data
相关代码:
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>文件上传</title> 6 <script src="jquery-1.12.4.min.js"></script> 7 <script src="public.js"></script> 8 <script> 9 $(function(){ 10 function callback(filename){ 11 $("#filename").val(filename); 12 $("#photo").hide(); 13 $("#up").val("已上传") 14 } 15 var xhr =creatxhr(); 16 $("#btn").click(function () { 17 var username = $("#username").val(); 18 var password = $("#pwd").val(); 19 var photo = $("#filename").val(); 20 var data = "username="+username+"&pwd="+password+"&photo="+photo; 21 xhr.open("post","demo.php"); 22 xhr.setRequestHeader("content-type","application/x-www-form-urlencoded"); 23 //ajax对象状态码发生改变时所触发的回调函数 24 xhr.onreadystatechange = function(){ 25 if(xhr.readyState == 4 && xhr.status == 200){ 26 $("#photo").show(); 27 $("#up").val("上传文件"); 28 $("#username").val(); 29 $("#pwd").val(); 30 $("#filename").val(); 31 if(xhr.responseText == "1"){ 32 console.log("注册成功"); 33 }else{ 34 console.log("注册失败"); 35 } 36 } 37 }; 38 //发送请求,此时状态码为2 39 xhr.send(data); 40 }); 41 42 }) 43 </script> 44 </head> 45 <body> 46 <form method="post" action="upload.php" target="ifm" enctype="multipart/form-data"> 47 <div class="form-group"> 48 <label for="username">用户名:</label> 49 <input type="text" id="username" placeholder="请输入用户名"> 50 </div> 51 <div class="form-group"> 52 <label for="pwd">密码:</label> 53 <input type="password" id="pwd" placeholder="请输入密码"> 54 </div> 55 <input type="hidden" id="filename"> 56 <div class="form-group"> 57 <label for="photo">照片:</label> 58 <input type="file" id="photo"> 59 <input type="submit" id="up" value="文件上传" name="up"> 60 </div> 61 <button id="btn">注册</button> 62 </form> 63 <iframe name="ifm" style="display: none;"></iframe> 64 </body> 65 </html>
1 <?php 2 //禁止客户端缓存数据 3 header("Cache-Control:no-cache,must-revalidate"); 4 if(isset($_POST['submit'])){ 5 //获取文件扩展名(jpg、png等) 6 $extname = strrchr($_FILES['photo']['name'],'.') 7 //生成新的文件名 8 $filename = time().$extname; 9 //文件上传 10 copy($_FILES['tmp_name'],'upload/'.$filename); 11 //如果上传成功的话,$filename返回的是120675321.jpg 12 将js语句输到iframe中,在iframe中执行parent.callback 13 //调用父窗口中的callback函数 14 echo "<script>parent.callback($filename);</script>"; 15 } 16 ?>
1 <?php 2 //禁止客户端缓存数据 3 header("Cache-Control:no-cache,must-revalidate"); 4 $username = $_POST['username']; 5 $password = $_POST['pwd']; 6 $photo = $_POST['photo']; 7 //连接数据库服务器、选择数据库 8 mysql_connect("localhost","root","111111"); 9 mysql_select_db("shop"); 10 mysql_query("set names gb2312"); 11 //sql语句 12 $sql = "insert into users (username,password,photo) values("$username","$password","$photo"); 13 $result =mysql_query($sql); 14 mysql_close(); 15 echo "1"; 16 ?>
无刷新是Ajax技术最大的特点,但不是Ajax技术出现的目的。
针对登录说明
如果使用传统的web应用程序,用户在登录时,整个页面重新刷新并请求新的页面地址,新的页面在验证之后,再重新跳转回来,但是对用户而言,除了登录页面之外,其他版本没有发生变化。
使用ajax程序,可以异步发送请求,改变的仅仅是登录页面,其他版块没有重新请求和刷新,所以节省网络传输的流量,可以快速获取服务器端数据。
五、利用xml实现数据传输
1、为什么是xml
主要是解决从服务器返回大量复杂的数据。
用户名是否可用 返回1/0
返回两个数的和 400
登录是否成功 true/false
数据是否插入成功 true/false
需要服务器端返回少量的、单一的数据
如果需要从服务器返回大量、复杂的数据,如何实现?
xml:服务器端返回xml数据
json:服务器端返回json数据
2、格式:
a、php解析xml
$dom = new DOMDocument();
$dom->loadXML($str);
$nd=$dom->getElementsByTagName("tagname");
$value = $nd->item(0)->nodeValue;
$xml = simplexml_load_string($str);
$first = $xml->first;
$second = $xml->second;
b、javascript解析xml
要求服务器返回的是text/xml
var xml = xmlHttp.responseXML;
node = xml.getElementsByTagName("tagname");
node[0].chlidNodes[0].nodeValue;
3、实现两个数的四则运算:
得到结果后,需要使用字符串连接成一个xml格式的字符串,如:需要一个根元素,下面子元素,最后是具体的值,连接时也可以使用<<<str创建xml字符串。
输出这个字符串,默认响应内容类型:text/html,也就是说客户端仍然把代码当做html类进行解析,ajax对象的responeXML是不能得到一个xmldom对象,必须设置响应头类型为text/xml;
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>四则运算</title> 6 <script src="jquery-1.12.4.min.js"></script> 7 <script src="public.js"></script> 8 <script> 9 $(function(){ 10 $("#btn").click(function(){ 11 var firstValue = $("#first").val(); 12 var secondsValue = $("#seconds").val(); 13 var data = "first="+firstValue+"&seconds="+secondsValue;//生成参数字符串 14 //创建ajax对象,此时状态码为0 15 var xhr =creatxhr(); 16 //初始化ajax对象 此时状态码为1 17 xhr.open("post","demo.php"); 18 xhr.setRequestHeader("content-type","application/x-www-form-urlencoded"); 19 //ajax对象状态码发生改变时所触发的回调函数 20 xhr.onreadystatechange = function(){ 21 //状态码为4说明接收完毕,做进一步的处理 22 if(xhr.readyState == 4 && xhr.status == 200){ 23 //xml->xmldom对象 24 var xml = xhr.responseXML;//得到ajax返回的xmldom对象 25 //xml.getElementsByTagName('jia')[0] 表示获取jia这个元素 26 //xml.getElementsByTagName('jia')[0].childNodes 表示获取jia元素下的所有子节点 27 //xml.getElementsByTagName('jia')[0].childNodes[0] 表示获取jia元素下的唯一文本节点。 28 //xml.getElementsByTagName('jia')[0].childNodes[0].nodeValue 表示获取jia元素下的唯一文本节点的值。 29 var str =xml.getElementsByTagName('jia')[0].childNodes[0].nodeValue; 30 var str1 =xml.getElementsByTagName('jian')[0].childNodes[0].nodeValue; 31 var str2 =xml.getElementsByTagName('cheng')[0].childNodes[0].nodeValue; 32 var str3 =xml.getElementsByTagName('chu')[0].childNodes[0].nodeValue; 33 } 34 }; 35 //发送请求,此时状态码为2 36 xhr.send(data); 37 }) 38 }) 39 </script> 40 </head> 41 <body> 42 <form> 43 第一个数:<input type="text" id="first"><br> 44 第二个数:<input type="text" id="seconds"><br> 45 <button id="btn">结果</button> 46 <span id="result" class="result"></span> 47 </form> 48 </body> 49 </html>
1 <?php 2 //禁止客户端缓存数据 3 header("Cache-Control:no-cache,must-revalidate"); 4 $first = $_POST['$first']; 5 $seconds = $_POST['$seconds']; 6 $result1 = $first+$seconds; 7 $result2 = $first-$seconds; 8 $result3 = $first*$seconds; 9 $result4 = $first/$seconds; 10 //要想返回xml,首先连接一个xml格式的字符串 11 $str="<root>"; 12 $str.="<jia>.$result1.</jia>"; 13 $str.="<jian>.$result2.</jian>"; 14 $str.="<cheng>.$result3.</cheng>"; 15 $str.="<chu>.$result4.</chu>"; 16 $str.="</root>"; 17 header("Content-type:text/xml"); 18 echo $str; 19 ?>
4、在页面加载之后,将goods表中所有数据显示在表格中。
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>把数据显示在表中</title> 6 <script src="jquery-1.12.4.min.js"></script> 7 <script src="public.js"></script> 8 <script> 9 $(function(){ 10 //创建ajax对象,此时状态码为0 11 var xhr =creatxhr(); 12 xhr.open("post","table.php"); 13 xhr.setRequestHeader("content-type","application/x-www-form-urlencoded"); 14 xhr.onreadystatechange = function(){ 15 if(xhr.readyState == 4 && xhr.status == 200){ 16 //xml->xmldom对象 17 var xml = xhr.responseXML;//得到ajax返回的xmldom对象 18 var goods = xml.getElementsByTagName('goods'); 19 var $tr ="<tr></tr>"; 20 for(var i=0;i<goods.length;i++){ 21 var strName =goods[i].childNodes[0].childNodes[0].nodeValue; 22 var strPrice =goods[i].childNodes[1].childNodes[0].nodeValue; 23 var $td0 = "<td>"+(i+1)+"</td>"; 24 var $td1 = "<td>"+strName+"</td>"; 25 var $td2 = "<td>"+strPrice+"</td>"; 26 $tr.append($td0).append($td1).append($td2); 27 $("#table tbody").append($tr); 28 } 29 } 30 xhr.send(null); 31 } 32 }) 33 </script> 34 </head> 35 <body> 36 <table id="table"> 37 <tr> 38 <td>编号</td> 39 <td>姓名</td> 40 <td>价格</td> 41 </tr> 42 </table> 43 </body> 44 </html>
查询goods表中所有数据,连接xml格式的字符串,表中有多少条数据,xml字符串就有几对goods标签
其中,name字段出现中文,需要进行转码,将gb2312->utf-8
最后输出xml字符串
1 <?php 2 //禁止客户端缓存数据 3 header("Cache-Control:no-cache,must-revalidate"); 4 $name = $_GET['name']; 5 //连接数据库服务器、选择数据库 6 mysql_connect("localhost","root","111111"); 7 mysql_select_db("shop"); 8 mysql_query("set names utf-8"); 9 //sql语句 10 $sql = "select name,price from goods order by id desc; 11 $result =mysql_query($sql); 12 //总行数 13 $num = mysql_num_rows($result); 14 mysql_close(); 15 $str = "<root>"; 16 for($i=0;$i<$num;$i++){ 17 $row = mysql_fetch_assoc($result); 18 $str.="<goods>"; 19 $str.="<name>".$row['name']."</name>"; 20 $str.="<price>".$row['price']."</price>"; 21 $str.="</goods>"; 22 } 23 str.="</root>"; 24 header("Content-Type:text/xml"); 25 echo $str; 26 ?>
六、利用json传输数据
1、为什么使用json传输数据
xml数据生成过于复杂、xml数据解析过于复杂。
2、关于json介绍
对象是属性的无序集合,在js中,可以使用{}模拟这个集合
语法:var json = {属性名:属性值,属性名:属性值}(属性名可以不加引号,也可以加单引号或双引号);
var json = [{ },{ },{ }];
3、用json表示具体的信息
a、表示一个人的信息
var person = {name:"zhangsan","age":18}; console.log("姓名:"+person.name+person.age)
b、表示多个人的信息
4、在php中如何使用json
a、json编码:json_encode();
b、json解码:json_decode();
生成json字符串
json表示大量数据,在php中表示多个、大量的数据可以数组、对象来表示
也就是说在php如果想生成json字符串,必须从数组、对象上生成。
解析json字符串:
json_decode函数可以将一个json格式的字符串进行解析,其中,这个函数的第二个参数表示解析方式。
true:解析到数组中
false:解析到对象中
默认为false
关于json保存中文的问题
目前,json只支持utf-8,如果想保存中文,必须进行转码。
5、JavaScript解析json
如果服务器端返回的是字符串,js中需要把字符串转换成json对象。
方法:eval("("+str+")");
var str = xmlHttp.responseText;比如服务器返回的是"{name:'zhangsan',age:30}";
//将字符串转换成json对象
var json = eval("("+str+")");
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>使用json把数据显示在表中</title> 6 <style> 7 table{ 8 border-collapse: collapse; 9 width:300px; 10 height:200px; 11 margin:0 auto; 12 text-align: center; 13 } 14 tr,td{ 15 border:1px solid #ccc; 16 } 17 </style> 18 <script src="jquery-1.12.4.min.js"></script> 19 <script src="public.js"></script> 20 <script> 21 $(function(){ 22 //创建ajax对象,此时状态码为0 23 var xhr =creatxhr(); 24 xhr.open("post","table.php"); 25 xhr.setRequestHeader("content-type","application/x-www-form-urlencoded"); 26 xhr.onreadystatechange = function(){ 27 if(xhr.readyState == 4 && xhr.status == 200){ 28 var value = xhr.responseText;//返回字符串 29 var $data = eval('('+value+')');//把返回的字符串转换为json对象 30 var $tr ="<tr></tr>"; 31 for(var i=0;i<$data.length;i++){ 32 var $td0 = "<td>"+(i+1)+"</td>"; 33 var $td1 = "<td>"+$data[i].name+"</td>"; 34 var $td2 = "<td>"+$data[i].price+"</td>"; 35 $tr.append($td0).append($td1).append($td2); 36 $("tbody").append($tr); 37 } 38 } 39 xhr.send(null); 40 } 41 }) 42 </script> 43 </head> 44 <body> 45 <table> 46 <tr> 47 <td>编号</td> 48 <td>姓名</td> 49 <td>价格</td> 50 </tr> 51 <tr> 52 <td>1</td> 53 <td>苹果</td> 54 <td>5</td> 55 </tr> 56 <tr> 57 <td>2</td> 58 <td>梨子</td> 59 <td>3</td> 60 </tr> 61 <tr> 62 <td>3</td> 63 <td>草莓</td> 64 <td>15</td> 65 </tr> 66 </table> 67 </body> 68 </html>
1 <?php 2 //连接数据库服务器、选择数据库 3 mysql_connect("localhost","root","111111"); 4 mysql_select_db("shop"); 5 mysql_query("set names utf-8"); 6 //sql语句 7 $sql = "select name,price from goods order by id desc; 8 $result =mysql_query($sql); 9 //总行数 10 $num = mysql_num_rows($result); 11 $data = array(); 12 for($i=0;$i<$num;$i++){ 13 $row = mysql_fetch_assoc($result); 14 $row['name'] = iconv('gb2312','utf-8',$row['name']); 15 $data[] = $row; 16 } 17 //关闭数据库 18 mysql_close(); 19 //输出json数据 20 echo json_encode($data); 21 ?>
php代码说明如下:
$row:一维数组 生成一个json格式的字符串
$data:二维数组 生成一个json数组格式的字符串
js代码说明如下:
一种返回的是:"{name:'zhangsan','password':'123456'}"; eval("("+str+")");
一种返回的是:"[{name:'zhangsan','password':'123456'},{name:'lisi',password:'111111'}]"; eval(str);