内容提纲:

1.XMLHttpRequest

2.GET与POST

3.封装Ajax

 发文不易,转载请注明链接出处,谢谢!

2005年Jesse James Garrett发表了一篇文章,标题为:Ajax:A new Approach to Web Applications。他在这篇文章里介绍了一种技术,用他的话说,就叫:Ajax,是Asynchronous JavaScript + XML的简写。这种技术能够想服务器请求额外的数据而无须卸载页面(即刷新),会带来更好的用户体验。一时间,席卷全球。

 

一.XMLHttpRequest

Ajax技术核心是XMLHttpRequest对象(简称XHR),这是由微软首先引入的一个特性,后来其他浏览器供应商都提供了相同的实现。在XHR出现之前,Ajax式的通信必须借助一些hack手段来实现,大多数是使用隐藏的框架或内嵌框架。

XHR的出现,为向服务器发送请求和解析服务器响应提供了流畅的接口。能够以异步方式从服务器获取更多的信息,这就意味着,用户只要触发某一事件,在不刷新网页的情况下,更新服务器最新的数据。

虽然Ajax中的x代表的是XML,但Ajax通信和数据格式无关,也就是说这种技术不一定使用XML

IE7+、Firefox、Opera、Chrome和Safari都支持原生的XHR对象,在这些浏览器中创建XHR对象可以直接实例化XMLHttpRequest即可。

var xhr = new XMLHttpRequest();

alert(xhr);                                                        //XMLHttpRequest

如果是IE6及以下,那么我们必须还需要使用ActiveX对象通过MSXML库来实现。在低版本IE浏览器可能会遇到三种不同版本的XHR对象,即MSXML2.XMLHttp、MSXML2.XMLHttp.3.0、MSXML2.XMLHttp.6.0。我们可以编写一个函数。

 function createXHR() {

        if (typeof XMLHttpRequest != 'undefined') {

               return new XMLHttpRequest();

        } else if  (typeof ActiveXObject != 'undefined') {

               var versions = [

                                                                       'MSXML2.XMLHttp.6.0',

                                                                       'MSXML2.XMLHttp.3.0',

                                                                       'MSXML2.XMLHttp'

               ];

               for (var i = 0; i < versions.length; i ++) {

                      try {

                             return new ActiveXObject(version[i]);

                      } catch (e) {

                             //跳过

                      }

               }

        } else {

               throw new Error('您的浏览器不支持XHR对象!');

        }

 }

 var xhr = createXHR();

在使用XHR对象时,先必须调用open()方法,它接受三个参数:要发送的请求类型(get、post)、请求的URL和表示是否异步。

xhr.open('get', 'demo.php', false);                        //对于demo.php的get请求,false同步

demo.php的代码如下:

<?php

echo Date('Y-m-d H:i:s');      //打印一个时间

?>

open()方法并不会真正发送请求,而只是启动一个请求以备发送。通过send()方法进行发送请求,send()方法接受一个参数,作为请求主体发送的数据。如果不需要(如用get方式)则必须填null。执行send()方法之后,请求就会发送到服务器上。

xhr.send(null);                            //发送请求

PS:如果没有向服务器端发送,火狐firebug无发送提示,如果有send()方法,则firebug会提示已发送(到火狐中用FireBug调试)。

当请求发送到服务器端,收到响应后,响应的数据会自动填充XHR对象的属性。那么一共有四个属性:

属性名

说明

responseText

作为响应主体被返回的文本

responseXML

如果响应主体内容类型是"text/xml"或"application/xml",则返回包含响应数据的XML DOM文档

status

响应的HTTP状态

statusText

HTTP状态的说明

接受响应之后,第一步检查status属性,以确定响应已经成功返回。一般以HTTP状态代码为200作为成功的标志。除了成功的状态代码,还有一些别的状态码:

HTTP状态码

状态字符串

说明

200

OK

服务器成功返回了页面

400

Bad Request

语法错误导致服务器不识别

401

Unauthorized

请求需要用户认证

404

Not found

指定的URL在服务器上找不到

500

Internal Server Error

服务器遇到意外错误,无法完成请求

503

ServiceUnavailable

由于服务器过载或维护导致无法完成请求

一般来说,我们判断HTTP状态值即可,不建议使用HTTP状态说明(statusText),因为在跨浏览器的时候,可能会不太一致。

 addEvent(document, 'click', function () {

        var xhr = new createXHR();

        xhr.open('get', 'demo.php?rand=' + Math.random(), false);  //设置了同步

        xhr.send(null);

        if (xhr.status == 200) {                              //如果返回成功了

               alert(xhr.responseText);                     //调出服务器返回的数据

        } else {

               alert('数据返回失败!状态代码:' + xhr.status + '状态信息:' + xhr.statusText);

        }

 });

PS:通过点击事件,不断的向服务器发送请求,然后服务器会实时的返回最新的数据,就是Ajax功能。

PS:IE浏览器第一次会向服务器端请求,获取最新数据,而第二次它就默认获取的是缓存数据,导致数据不是最新的,怎么处理缓存?可以使用JS随机字符串:Math.random()。

以上的代码每次点击页面的时候,返回的时间都是实时的,说明都是通过服务器及时加载回的数据。那么我们也可以测试一下在非Ajax下的情况。

创建一个demo2.php文件,使用非Ajax:

 <script type="text/javascript" src="base.js"></script>

 <script type="text/javascript">

        addEvent(document, 'click', function () {       //当不断点击页面,返回的时间不发生变化

               alert("<?php echo Date('Y-m-d H:i:s')?>");

        });

 </script>

同步调用固然简单,但使用异步调用才是我们真正常用的手段。使用异步调用的时候,需要触发readystatechange事件,然后检测readyState属性即可。这个属性有五个值:

状态

说明

0

未初始化

尚未调用open()方法

1

启动

已经调用open()方法,但尚未调用send()方法

2

发送

已经调用send()方法,但尚未接受响应

3

接受

已经接受到部分响应数据

4

完成

已经接受到全部响应数据,而且可以使用

//异步方式

 addEvent(document, 'click', function () {

        var xhr = new createXHR();

        xhr.onreadystatechange = function () {

               if (xhr.readyState == 4) {

                      if (xhr.status == 200) {

                             alert(xhr.responseText);

                      } else {

                             alert('数据返回失败!状态代码:' + xhr.status + '状态信息:'+ xhr.statusText);

                      }

               }

        };

        xhr.open('get', 'demo.php?rand=' + Math.random(), true);

        xhr.send(null);

        //xhr.abort();                //取消异步请求    

 });

PS:使用abort()方法可以取消异步请求,放在send()方法之前会报错。放在responseText之前会得到一个空值。

二.GET与POST

在提供服务器请求的过程中,有两种方式,分别是:GET和POSTAjax使用的过程中,GET的使用频率要比POST高。

在Web程序中:

GET一般是URL提交请求,比如:

demo.php?name=Lee&age=100

POST一般是Web表单提交, 比如:

<form method="post">

  <input type="text" name="name" value="Lee">

  <input type="text" name="age" value="100">

</form>

在了解这两种请求方式前,我们先了解一下HTTP头部信息,包含服务器返回的响应头信息和客户端发送出去的请求头信息。我们可以获取响应头信息(不可以设置)或者设置请求头信息(不可以获取)。我们可以在Firefox浏览器的firebug查看这些信息。

 addEvent(document, 'click', function () {

        var xhr = createXHR();        

        xhr.onreadystatechange = function () {

               if (xhr.readyState == 4) {

                      if (xhr.status == 200) {                          

                             //alert(xhr.getAllResponseHeaders());           //获取全部响应头信息                         

                             //alert(xhr.getResponseHeader('Content-Type'));      //获取单个响应头信息
} else { alert('获取数据错误!错误代号:' + xhr.status + ',错误信息:' + xhr.statusText); } } }; xhr.open('get', 'demo.php?rand=' + Math.random(), true);
xhr.setRequestHeader('myheader','Lee'); //设置请求头信息,一般没什么用,在POST提交请求有用
xhr.send(null); });

PS:我们只可以获取服务器返回回来响应头信息,无法获取向服务器提交的请求头信息,自然自定义的请求头,在JavaScript端是无法获取到的。

GET请求

GET请求是最常见的请求类型,最常用于向服务器查询某些信息。必要时,可以将查询字符串参数追加到URL的末尾,以便提交给服务器。

xhr.open('get', 'demo.php?rand=' + Math.random() + '&name=Koo', true);

注意:通过URL后的问号给服务器传递键值对数据,服务器接收到然后返回响应数据。特殊字符传参产生的问题可以使用encodeURIComponent()进行编码处理;中文字符的返回及传参,可以将页面保存和设置为utf-8格式即可。

//一个通用的URL提交函数

 function addURLParam(url, name, value) {

        url += (url.indexOf('?') == -1 ? '?' : '&');                    //判断的url是否有已有参数

        url += encodeURIComponent(name) + '=' + encodeURIComponent(value);

        alert(url);

        return url;

 }

PS:当没有encodeURIComponent()方法时,在一些特殊字符比如“&”,会出现错误导致无法获取。

代码汇总:

demo.php代码部分:

 <?php

        header('Content-Type: text/html;charset=utf-8');

        //echo Date('Y-m-d H:i:s');

        print_r($_GET);

        print_r($_POST);

        //if ($_GET['name'] == 'Lee') {

        //     echo '中文';

        //}

        if ($_POST['name'] == 'Lee') {

               echo '中文';

        }

 ?>

//GET请求

 addEvent(document, 'click', function () {

        var xhr = createXHR();        

        var url = 'demo.php?rand=' + Math.random();

        url = params(url, 'name', 'Lee');

        url = params(url, 'age', 100);

        alert(url);

        xhr.onreadystatechange = function () {

               if (xhr.readyState == 4) {

                      if (xhr.status == 200) {

                             alert(xhr.responseText);

                      } else {

                             alert('获取数据错误!错误代号:' + xhr.status + ',错误信息:' + xhr.statusText);

                      }    

               }

        };

        xhr.open('get', url, true);

        xhr.send(null);                    

 });

 function params(url, name, value) {

        url += url.indexOf('?') == -1 ? '?' : '&';

        url += encodeURIComponent(name) + '=' + encodeURIComponent(value);

        return url;

 }

POST请求

POST请求可以包含非常多的数据,我们在使用表单提交的时候,很多就是使用的POST传输方式。

xhr.open('post', 'demo.php', true);

而发送POST请求的数据,不会跟在URL的尾巴上,而是通过send()方法向服务器提交数据。

xhr.send('name=Lee&age=100');

一般来说,向服务器发送POST请求由于解析机制的原因,需要进行特别的处理。因为POST请求和Web表单提交是不同的,需要使用XHR来模仿表单提交。代码如下:

xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');

代码汇总:

 addEvent(document, 'click', function () {

        var xhr = createXHR();        

        var url = 'demo.php?rand=' + Math.random();

        xhr.onreadystatechange = function () {

               if (xhr.readyState == 4) {

                      if (xhr.status == 200) {

                             alert(xhr.responseText);

                      } else {

                             alert('获取数据错误!错误代号:' + xhr.status + ',错误信息:' + xhr.statusText);

                      }    

               }

        };

        xhr.open('post', url, true);                           //第一步改为post

        xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');     //第三步,模拟表单提交      

      xhr.send('name=Lee&age=100');                //第二步,将名值对放入send方法里(其实也需要像get一样进行编码) 

 });

PS:从性能上来讲POST请求比GET请求消耗更多一些,用相同数据比较,GET最多比POST快两倍。

JSON数据也可以使用Ajax来回调访问:

var url = 'demo.json?rand=' + Math.random();

var box = JSON.parse(xhr.responseText);

 

三.封装Ajax

因为Ajax使用起来比较麻烦,主要就是参数问题,比如到底使用GET还是POST;到底是使用同步还是异步等等,我们需要封装一个Ajax函数,来方便我们调用。部分核心代码如下:

//封装ajax

 function ajax(obj) {

        var xhr = createXHR();

        obj.url = obj.url + '?rand=' + Math.random();

        obj.data = params(obj.data);

        if (obj.method === 'get') obj.url += obj.url.indexOf('?') == -1 ? '?' + obj.data : '&' + obj.data;          //1.GET方式发送数据

        if (obj.async === true) {                     //异步方式会执行这儿

               xhr.onreadystatechange = function () {

                      if (xhr.readyState == 4) {

                             callback();                        //调用callback函数

                      }

               };

        }

        xhr.open(obj.method, obj.url, obj.async);

        if (obj.method === 'post') {     //2.POST方式发送数据

               xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');

               xhr.send(obj.data); 

        } else {

               xhr.send(null);

        }

        if (obj.async === false) {     //同步方式会执行这儿

               callback();                                        //调用callback函数回调

        }

        function callback() {                              //封装为callback函数,方便上面调用

               if (xhr.status == 200) {

                      obj.success(xhr.responseText);       //调用obj的success方法回调传递参数

               } else {

                      alert('获取数据错误!错误代号:' + xhr.status + ',错误信息:' + xhr.statusText);

               }    

        }

 }

For my lover and

Thank you, Mr.Lee!

JavaScript基础---AJAX的更多相关文章

  1. JavaScript基础系列目录(2014.06.01~2014.06.08)

    下列文章,转载请亲注明链接出处,谢谢! 链接地址: http://www.cnblogs.com/ttcc/tag/JavaScript%20%E5%9F%BA%E7%A1%80%E7%9F%A5%E ...

  2. javascript基础-HTML5

    跨文档消息(Web Messaging cross-document messaging) 原理 往有关联(同一框架/弹出)的文档传递数据. Message Channel在javascript基础- ...

  3. 【Java EE 学习 31】【JavaScript基础增强】【Ajax基础】【Json基础】

    一.JavaScript基础增强 1.弹窗 (1)使用window对象的showModelDialog方法和showModelessDialog方法分别可以弹出模式窗口和非模式窗口,但是只能在IE中使 ...

  4. (转)JAVA AJAX教程第二章-JAVASCRIPT基础知识

    开篇:JAVASCRIPT是AJAX技术中不可或缺的一部分,所以想学好AJAX以及现在流行的AJAX框架,学好JAVASCRIPT是最重要的.这章我给大家整理了一些JAVASCRIPT的基础知识.常用 ...

  5. 【javascript】ajax 基础

    什么是 ajax ajax 即“Asynchronous JavaScript and XML”(异步 JavaScript 和 XML),也就是无刷新数据读取. http 请求 首先需要了解 htt ...

  6. 一步步学习javascript基础篇(0):开篇索引

    索引: 一步步学习javascript基础篇(1):基本概念 一步步学习javascript基础篇(2):作用域和作用域链 一步步学习javascript基础篇(3):Object.Function等 ...

  7. 最新JavaScript、Ajax典藏级学习资料下载分类汇总 (2011年12月21日更新)

    其他网站开发相关资料            超强HTML和xhtml,CSS精品学习资料下载汇总                                               最新htm ...

  8. 初识JavaScript,Ajax,jQuery,并比较三者关系

    一.基本认识 1.JavaScript 定义: javaScript的简写形式就是JS,是由Netscape公司开发的一种脚本语言,一种广泛用于客户端Web开发的脚本语言,常用来给HTML网页添加动态 ...

  9. JavaScript基础---语言基础(1)

    写在前面: 通过四篇博客把JS基础中的基础整理一下,方便自己查阅,这些内容对于实际项目开发中也许并不会在意,但是作为JS的语言基础,自觉还是应该熟悉.在完成这三篇博客(JavaScript基础---语 ...

随机推荐

  1. Windows 网络问题

    一.问题描述 每次重启后电脑的ip地址或无故没掉,或不能正常连网,要重新设置ip才能上网.   二.解决方法 在DOS窗口执行 netsh winsock reset netsh int ip res ...

  2. WDK编程的一些特殊点

    函数的多线程安全性在内核编程中比用户态应用程序的编程更常见. 调用源 运行环境 原因 driverEntry,DriverUnload 单线程 这两个函数由系统进程的单一线程调用,不会出现多线程同时调 ...

  3. 这一路走来,冷暖自知 (附算法demos)

    最近半年多,除了“一键修图”算法之外我还做了其他什么算法? 1.实时单图HDR算法(颜色矫正,智能曝光) 2.多图曝光融合HDR算法(最高支持八百万像素左右) 3.模拟热能探测算法 4.防伪探测算法 ...

  4. 2014 UESTC 暑前集训队内赛(2) 部分解题报告

    B.Cuckoo for Hashing 模拟题. 代码: #include <iostream> #include <cstdio> #include <cstring ...

  5. android 知识点收集

    1.  计算时间流逝请使用SystemClock.elapsedRealtime... currentTimeMillis会受系统时钟影响  //未验证 2.  android app私有文件的目录 ...

  6. Linux下检测IP地址冲突及解决方法

    问题说明:在公司办公网内的一台物理机A上安装了linux系统(ip:192.168.9.120),在上面部署了jenkins,redmine,svn程序.由于是在办公网内,这台机器和同事电脑都是在同一 ...

  7. prepareStatement createStatement

    preparedstatement具备很多优点,开发者可能通常都使用它,只有在完全是因为性能原因或者是在一行sql语句中没有变量的时候才使用通常的statement. preparedstatemen ...

  8. S2--《深入.NET平台和C#编程》

    第一章    深入.NET框架 1.1  Microsoft  .NET框架概述 .NET框架的优势 * 提供了一个面向对象的编程环境,完全支持面向对象编程,.NET 框架提高了软件的可复用性,可扩展 ...

  9. U5398 改数(num)

    U5398 改数(num) 5通过 28提交 题目提供者52zyz 标签 难度尚无评定 提交 最新讨论 暂时没有讨论 题目背景 又是一年NOIP,科学馆的五楼:“我们看下这道题,我们来模拟一下…2,3 ...

  10. 错题802-java

    1.list是一个ArrayList的对象,哪个选项的代码填到//todo delete处,可以在Iterator遍历的过程中正确并安全的删除一个list中保存的对象?() Iterator it = ...