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>
View Code

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 ?>
View Code

 

前瞻 : 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>
View Code

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>
View Code

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>
View Code

 

输出:

 

 

posted @ 2014-01-02 20:23  tlijian1989  阅读(286)  评论(0)    收藏  举报