AJAX专题
所谓AJAX就是指:页面在不刷新,不跳转的情况下,利用XMLHttpRequest对象像服务器发送HTTP请求.也就是JS的网络化.
早些年是通过HTTP发送204<例:header('http/1.1 204 No-Content');>,ifram框架,src加载等方法也达到页面在不刷新,不跳转的情况下向服务器请求.
AJAX的核心就是 XMLHttpRequest对象 ,一个专门发送HTTP请求工具.
如何使用XMLHttpRequest对象做AJAX请求?
要解答这个这个问题要先分析以下三点.
分析一 : XMLHttpRequest是个对象 ,那么如何创建这个对象?
答: 按标准,new XMLHttpRequest() 即可得到对象.
但在低版本的IE中,需要用 new ActiveXObject(Mircrosoft.XMLHTTP) 得到对象.
分析二 : 如何发送HTTP请求?
答: var xhr = new XMLHttpRequest();
要发送HTTP请求,首先要建立连接.用open方法建立
xhr.open('get','./1.php',true); // 参数1 请求的方式(常用的GET/POST) 参数2 请求路径 参数3 true是异步模式 false是同步模式
xhr.send(null); //发送HTTP请求 .如果是GET请求,参数传NULL即可,如果是POST,里面传一个josn参数 如:{name:'lijian',age='23'}
分析三 : 返回结果如何得到?
答: xhr.responseText
服务器接收到的响应内容(不包括头部),也就是请求的那个页面输出的内容
如果请求状态小于3,则responseText就是个空字符串,如果是3,则返回目前
接收到的内容,当4时保存完整的响应内容
xhr.responseXML
响应内容解析为XML并作为document对象返回
XMLHttpRequest对象的属性
1 readyState HTTP请求的状态,从0-4. 4代表完成
XMLHttpRequest对象被实例后 readyState = 0
当open建立连接 readyState = 1
返回完header头信息后 readyState = 2
接收完 主体信息 readyState = 3
连接关闭,完成请求 readyState = 4
2 onreadystatechange 这是个事件属性(如同onclick,onmouseover等),当HTTP请求的状态(state)发生改变时,它会自动触发.
例子: xhr.onreadystatechange = function(){
if(xhr.readyState == 4){
alert( xhr.responseText);
}
}
注: 每当请求的状态发生改变就触发onreadystatechange事件.当HTTP请求结束(值等于4)后.返回结果.
3 state HTTP请求完成后,返回的状态码.
4 statusText 状态代码对应的文字说明
XMLHttpRequest对象的方法
open() 初始化请求参数
send() 发送请求
abort() 取消当前响应,当请求时间太长,而且请求不再必要的时候,这个方法会将XMLHttpRequest对象重置为readyState为0的状态
getResponseHeader() HTTP请求完成后,取得指定头信息.例: xhr.getResponseHeader('content-type') 返回头信息content-type的值(内容的类型).
getAllResponseHeaders() 取得全部头信息. xhr.getAllResponseHeaders();
setResponseHeader() 发送HTTP请求前(send()方法之前),设置请求的头部信息.
AJAX返回值的类型
注: AJAX返回值的基本类型只有2种.text类型,xml类型.还有两种html类型,json类型 是text类型衍生出来的.
text类型 纯文本.应用场景: 一般返回较短,具有标志的字符串,如,0/1, succ/fail, 已注册,未注册等.
例子:
<script type="text/javascript">
var xhr = new XMLHttpRequest();
xhr.open('get','./1.php');
xhr.send(null);
xhr.onreadystatechange = function(){
if(xhr.readyState == 4){
alert(xhr.responseText); //返回文本内容
}
}
</script>
输出:
XML类型
例子:
<script type="text/javascript">
var xhr = new XMLHttpRequest();
xhr.open('get','./1.php');
xhr.send(null);
xhr.onreadystatechange = function(){
if(xhr.readyState == 4){
var xml = xhr.responseXML; //返回结果是xml对象
var book = xml.getElementsByTagName('item')[0]; //取item节点
var name = book.childNodes[0].nodeValue; //item的值
alert(name);
}
}
</script>
1.php的内容
输出:
JSON格式(应用场景: 返回数组或对象等格式化数据)
1.php的内容
<script type="text/javascript">
var xhr = new XMLHttpRequest();
xhr.open('get','./1.php');
xhr.send(null);
xhr.onreadystatechange = function(){
if(xhr.readyState == 4){
var json = xhr.responseText; //实质传来的还是text格式.只是内容上和json格式一样.通过json来转成真正的json对象
var json = eval('('+json+')');
console.log(json);
}
}
</script>
输出:
AJAX上传
从原理上讲AJAX是无法上传文件的. 从HTTP协议的角度讲,上传文件.则需要把文件的内容上传给服务器.既然要上传给服务器那么XMLHttpRequest对象就要
获得文件的内容.但出于安全考虑JS是无法读取文件内容.所以AJAX上传从原理上讲是无法实现的.
但是网上一些AJAX上传插件是怎么实现上传的呢?
1 . 用 iframe 实现伪AJAX
2 . 用flash实现. 如swfupload
3. 用HTML5 .HTML5已经添加了文件读取API,使AJAX上传有了可能.
利用 iframe 实现"AJAX"上传
HTML文件
1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> 2 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"> 3 <head> 4 <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"> 5 <title>Document</title> 6 </head> 7 <script type="text/javascript"> 8 function upload(){ 9 //form节点对象 10 var formDom = document.getElementsByTagName('form')[0]; 11 //创建iframe标签 12 var iframe = document.createElement('iframe'); 13 //设置iframe的name属性 14 iframe.setAttribute('name','up'); 15 //iframe隐藏掉 16 iframe.setAttribute('width','0'); 17 iframe.setAttribute('height','0'); 18 iframe.setAttribute('frameBorder','0'); 19 //给from标签加一个target属性,与iframe的name值相同 20 formDom.setAttribute('target','up'); 21 document.getElementsByTagName('body')[0].appendChild(iframe); 22 23 } 24 </script> 25 <body> 26 <h2 id="msg"></h2> 27 <form action="1.php" method="post" enctype="multipart/form-data" onsubmit="return upload()"> 28 档案 : <input type="file" name="file"/><br /> 29 <input type="submit" value="提交"/><br /> 30 </form> 31 32 </body> 33 </html>
PHP文件
1 <?php 2 $error = $_FILES['file']['error']; 3 $old_dir = $_FILES['file']['tmp_name']; 4 $new_dir = './123.txt'; 5 6 if($error == 0){ 7 $re = move_uploaded_file($old_dir,$new_dir); 8 if($re){ 9 $str = '<script type="text/javascript">'; 10 $str .= 'var msg = window.parent.document.getElementById("msg");'; 11 $str .= 'msg.appendChild(document.createTextNode("上传成功"));'; 12 $str .= '</script>'; 13 echo $str; 14 } 15 } 16 17 ?>
前瞻 : HTML5的 FormData (表单数据对象)
前言 : 还记得XMLHttpRequest对象发送请求的send方法吗?
当GET请求时,参数都会直接写在URL中.所以send方法只传了一个NULL. 如: xhr.send(null);
但是POST请求中.参数就必须要写进send方法里了.如xhr.send('name=lijian&age=23') 或者用JSON格式 xhr.send({name:'lijian',age:23})
这样拼接参数略显麻烦. 此时用HTML5的 FormData 就可以省去麻烦.
简介 : FormData是表单数据对象.这是HTML5新增的API,它能以表单对象(form元素的节点对象)为参数,自动把表单数据打包.
当然AJAX发送数据时只要传入ForData对象就行了,它会自动发送表单各个数据.
例子:
HTML文件
1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> 2 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"> 3 <head> 4 <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"> 5 <title>Document</title> 6 </head> 7 <script type="text/javascript"> 8 function sub(){ 9 //form表单对象 10 var formDOM = document.getElementsByTagName('form')[0]; 11 //new个formdata对象.传入from表单对象做参数 12 var formData = new FormData(formDOM); 13 var xhr = new XMLHttpRequest(); 14 xhr.open('POST','./1.php'); 15 //发送数据只要传一个formData对象 16 xhr.send(formData); 17 18 xhr.onreadystatechange=function(){ 19 if(xhr.readyState == 4){ 20 //打印返回的数据 21 console.log(xhr.responseText); 22 } 23 } 24 return false; 25 } 26 </script> 27 <body> 28 <form action="1.php" method="post" onsubmit="return sub()"> 29 姓名 : <input type="text" name="name"/> 30 <br /><br /> 31 年龄 : <input type="text" name="age"/> 32 <br /><br /> 33 <input type="submit" value="提交"/> 34 </form> 35 </body> 36 </html>
PHP文件
1 <?php 2 print_r($_POST); 3 ?>
输出:
如果没有form表单,能不能传数据进去呢?
可以的, FormData有个append方法可以传入数据.
例子
1 var formData = new FormData(); 2 formData.append('say','hello'); 3 formData.append('play','game');
前瞻 : HTML5的 FILES (文件对象)
files对象能获得上传文件的对象.文件对象里包含着文件相关信息.
<script type="text/javascript">
function sub(){
//form表单对象
var input = document.getElementsByTagName('input')[0].files;
console.log(input);
return false;
}
</script>
<body>
<form action="1.php" method="post" onsubmit="return sub()">
上传文件 <input type="file" name="f1"/>
<br />
<input type="submit" value="上传"/>
</form>
</body>
输出:
上面输出的是文件列表对象.而第0个单元 .则是文件对象.
var input = document.getElementsByTagName('input')[0].files[0];
输出:
这个就是文件对象了.里面包含了很多有用的信息.
获得了文件对象.就可以将文件对象传到FormData对象里,用AJAX进行上传.这就是之前提到的"用HTML5 .HTML5已经添加了文件读取API,使AJAX上传有了可能.".
例子:
HTML
1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> 2 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"> 3 <head> 4 <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"> 5 <title>Document</title> 6 </head> 7 <script type="text/javascript"> 8 function sub(){ 9 //form表单对象 10 var ob_file = document.getElementsByTagName('input')[0].files[0]; 11 12 //new个formdata对象.传入from表单对象做参数 13 var formData = new FormData(); 14 formData.append('file',ob_file); 15 16 var xhr = new XMLHttpRequest(); 17 xhr.open('POST','./1.php'); 18 //发送数据只要传一个formData对象 19 xhr.send(formData); 20 21 xhr.onreadystatechange=function(){ 22 if(xhr.readyState == 4){ 23 //打印返回的数据 24 console.log(xhr.responseText); 25 } 26 } 27 return false; 28 } 29 </script> 30 <body> 31 <form action="1.php" method="post" onsubmit="return sub()"> 32 上传文件 <input type="file"/> 33 <br /> 34 <input type="submit" value="上传"/> 35 </form> 36 </body> 37 </html>
PHP
<?php
print_r($_FILES);
?>
输出:
前瞻: 带进度条的AJAX上传
HTML5中XMLHttpRequest对长传过程还添加了一个上传过程事件onprogress.
想要上传时有进度条必须要有两个基本的信息.
1 文件总大小
2 当前上传的大小
在onprogress事件中,就可以得到这两个信息.
具体思路 ,上传过程中不断onprogress事件函数,获取当前上传大小/文件总大小,更新页面的进度条.
下面看一下onprogress事件.如何写.
1 var xhr = new XMLHttpRequest(); 2 xhr.upload.onprogress = function (ev) { 3 console.log(ev); //打印下这个对象. 4 }
上面说到 onprogress事件可以获得文件的相关信息.比如文件大小.当前上传的大小 等等.那如何得到这些信息?
答: 通过事件对象.事件对象是系统自动传的.下面看下如何得到事件对象.
var xhr = new XMLHttpRequest(); xhr.upload.onprogress = function (ev) { console.log(ev); //ev就是事件对象.是系统自动传入.我们只管调用就行. }
输出: 可以看到事件对象里的信息很多.暂时只看红线部分.这两个参数就是 "loaded 当前上传的大小" 和 total 文件总大小.
下面看下 AJAX上传进度条 具体是如何实现的?
PHP文件
1 <?php 2 $old = $_FILES['file']['tmp_name']; 3 $new = uniqid().'.jpg'; 4 5 echo move_uploaded_file($old,$new); 6 ?>
HTML文件
1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> 2 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"> 3 <head> 4 <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"> 5 <title>Document</title> 6 </head> 7 <script type="text/javascript"> 8 9 function sub(){ 10 // 创建FormData对象 11 var fd = new FormData(); 12 13 // 获取文件对象 14 var pic = document.getElementsByTagName('input')[0].files[0]; 15 16 // 把文件内容追加到表单数据里 17 fd.append('file',pic); 18 19 20 var xhr = new XMLHttpRequest(); 21 xhr.open('POST','1.php',true); 22 23 24 // 利用XHR2的新标准,为上传过程,写一个监听函数 25 xhr.upload.onprogress = function (ev) { 26 var percent = (ev.loaded / ev.total)*100; 27 //进度条. 通过改变将div的宽度来达到进度条效果 28 var divDom = document.getElementsByTagName('div')[1]; 29 var spanDom = document.getElementsByTagName('span')[0]; 30 //进度数字 31 spanDom.innerHTML = parseInt(percent)+'%'; 32 //进度条 33 divDom.style.width = percent+'%'; 34 } 35 36 xhr.onreadystatechange = function(){ 37 if(xhr.readyState ==4 ){ 38 console.log(xhr.responseText); 39 } 40 } 41 xhr.send(fd); 42 return false; 43 } 44 45 46 </script> 47 <style> 48 .loaded_box{ 49 margin-top: 10px; 50 width: 200px; 51 height: 8px; 52 border: 1px solid lightblue; 53 } 54 .loaded{ 55 width: 0%; 56 height: 8px; 57 background: lightblue; 58 } 59 </style> 60 <body> 61 <form action="1.php" method="post" enctype="multipart/form-data" onsubmit="return sub()"> 62 上传文件 <input type="file" name="file"/> 63 <br /> 64 <input type="submit" value="上传" name="file"/> 65 </form> 66 <div class="loaded_box"> 67 <div class="loaded"></div> 68 <span>0%</span> 69 </div> 70 </body> 71 </html>
输出:

浙公网安备 33010602011771号