1、AJAX 简介
AJAX(音译为:阿贾克斯) = Asynchronous JavaScript and XML(异步的 JavaScript 和 XML),是指一种创建交互式网页应用的网页开发技术,也就是在无需重新加载整个网页的情况下,能够更新部分网页的技术。AJAX 不是新的编程语言,而是一种使用现有标准的新方法,是一种用于创建快速动态网页的技术,通过在后台与服务器进行少量数据交换,AJAX 可以使网页实现异步更新。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新,传统的网页(不使用 AJAX)如果需要更新内容或者用户注册信息、提交表单等,必需重新加载整个网页页面。所以说 AJAX 是一种与服务器交换数据并更新部分网页的艺术,因此我们必须掌握 AJAX 这种技术。
AJAX 是基于现有的 Internet 标准,并且联合使用它们:
①、XMLHttpRequest 对象 (异步的与服务器交换数据)
②、JavaScript/DOM (信息显示/交互)
③、CSS (给数据定义样式)
④、XML (作为转换数据的格式)
AJAX 的核心是 JavaScript 对象 XMLHttpRequest,他是一种支持异步请求的技术,也就是 XMLHttpRequest 赋予了我们可以使用 JS 向服务器提出请求并处理响应的能力,而不阻塞用户,通过这个对象,JS 可在不重载页面的情况下与 Web 服务器交换数据。AJAX 在浏览器与 Web 服务器之间使用异步数据传输(HTTP 请求),这样就可使网页从服务器请求少量的信息,而不是整个页面。AJAX 是一种独立于 Web 服务器软件的浏览器技术,也就是 AJAX 应用程序独立于浏览器和平台!
那么,简单说,AJAX 就是可以让 JS 去读取服务器上的数据,他的功能是可以在无需刷新页面的前提下,去服务器读取或者发送数据。可用来与 JSON 文件进行交互式通信,也可用来与数据库进行动态通信,还可用于创造动态性更强的应用程序。最常见的应用就是用户登录,在登录时,他就可以判断用户输入是否正确,如果输入正确,就直接显示用户信息,如果输入错误,提示错误信息,并不需要刷新页面。
2、配置服务器
AJAX 应用是异步更新,读取服务器上的数据,那到底服务器是什么东西呢?其实服务器就相当于 PC ,我们在平时浏览网页时,只需要在地址栏输入相应的网址,就可以浏览对应的页面,这些页面不可能存储在个人电脑中,那得需要多大的硬盘,并且还有其他影响因素,所以这些网页就存储在对应的服务器上,比如百度的服务器、新浪的服务器,其实服务器跟我们平时用的电脑没有什么多大的区别,个人计算机也可以作为服务器,甚至是手机之类的东西也可以作为服务器,比如我们用手机给电脑传照片,可以不通过数据线,使用 WIFI 或者腾讯提供的功能,就可以很轻松的完成传输过程,这时候手机就充当了服务器的角色,只不过性能比较差,仅对这一台机器提供服务而已。那么 Web 服务器就是可以同时对很多人提供服务,性能更强大。
在学习 AJAX 时,就必须配置个人服务器,也就是要在本机搭建服务器程序,方便我们调试代码。通常都会使用 WAMP 来搭建服务器,本地服务器搭建程序有很多种,大家可以选一种自己喜欢的来搭建,这里就以 WAMP 为例,WAMP 即 Windows 下的 Apache + Mysql + PHP 集成安装环境,也就是 Win 平台上的服务器程序,而通常都使用 WampServer 这一服务器软件。我这里安装的是 WampServer 2.5,大家可以百度搜索 wamp 找到2.5版本下载安装,建议将程序装在 D 盘,安装完成之后,打开程序,在桌面右下角有一个 W 的图标,通常都为绿色,可在图标上点击右键,选择倒数第二个选项切换为中文,切换完成之后,接下来就是配置了,下面是我在网上找到的配置方法,并且使用没有问题,写在这里也省的去找了,现在 WampServer 已经更新到3.0版本了,根据安装的版本不同在百度搜索配置方法,都是一堆堆的。
首先,用编辑器打开安装目录:D:\wamp\bin\apache\apache2.4.9\conf\httpd.conf 文件
在516行或者搜索关键词找到:
#Include conf/extra/httpd-manual.conf
将前面的井号去掉。
然后,再打开:D:\wamp\bin\apache\apache2.4.9\conf\extra\httpd-vhosts.conf 文件
在代码最后添加如下内容:
<VirtualHost *:80>
DocumentRoot "D:/wamp/www"
ServerName www.abc.com
ServerAlias www.abc.comabc.com
<Directory "D:/wamp/www">
Options Indexes FollowSymLinks
AllowOverride All
Require all granted
</Directory>
</VirtualHost>
www.abc.com 为个人站点地址,可以自行定义。
最后,打开:C:\Windows\System32\drivers\etc\hosts 文件
添加:127.0.0.1 www.abc.com
重新启动WAMP。
在需要做测试时,将页面保存在 D:/wamp/www 路径下,文件名保存为 index.html,然后在浏览器地址栏输入 abc.com 就可以打开刚才保存的页面。
如果打开不成功,可百度搜索解决办法,可能是80端口被占用了。
这里需要注意一下,放在服务器下的文件不能用中文命名。
3、AJAX 基础
首先,我们先来看一个 AJAX 应用的实例:请求并显示静态 TXT 文件
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="UTF-8"> 5 <title>AJAX 实例</title> 6 <script> 7 function ajax(){
8 var oAjax = new XMLHttpRequest();
9
10 oAjax.onreadystatechange = function (){
11 if(oAjax.readyState == 4 && oAjax.status == 200){
12 alert(oAjax.responseText);
13 }
14 }
15
16 oAjax.open('GET', 'ajax/demo.txt', true);
17 oAjax.send();
18 }
19 </script>20 </head>21 <body>22 <button type="button" οnclick="ajax()">读取</button>23 </body>24 </html>
我们需要把页面保存在 WAMP 安装目录下 www 根目录中,并且新建一个文件夹命名为 ajax,用于存储 TXT 文件,命名为 demo.txt,文件中可以随意输入点文字,用作演示。然后通过我们自定义的个人站点,在浏览器中打开页面,当点击读取按钮后,弹出 TXT 文件中的内容。
通过上面的实例,我们就可以看到,实际上 AJAX 的作用就是从服务器上读取一个文件,并且把这个文件内容返回给我们,让我们处理。
这里需要注意的是字符集编码问题,在使用 AJAX 时,所有的文件都必须是统一的编码格式,包括 HTML 、JS 文件和被读的文件,比如都是 UTF-8 或者都是 GB2312,上面实例中用于演示的 TXT 文件,默认输入英文,在保存时默认编码为 ANSI,如果我们输入的是汉字,在保存时不改为与页面相同的编码格式 UTF-8,那么在点击按钮后,网页上就显示的乱码,所以在保存时,一定要注意切换文件的编码格式。
下面我们来分析一下 AJAX 的工作原理。
4、XHR 创建对象
XHR 是 XMLHttpRequest 的简写,是 AJAX 的基础,用于在后台与服务器交换数据。
所有现代浏览器(IE7+、Firefox、Chrome、Safari 以及 Opera)均内建 XMLHttpRequest 对象,老版本的 IE 浏览器(IE6)则使用 ActiveXObject,为了兼容各种浏览器,可以做一个判断,如果支持 XMLHttpRequest 对象,则创建该对象,如果不支持,则创建 ActiveXObject 。
1 var oAjax;
2 // IE7+, Firefox, Chrome, Opera, Safari3 if(window.XMLHttpRequest){
4 oAjax = new XMLHttpRequest();
5 }
6 // IE67 else{
8 oAjax = new ActiveXObject("Microsoft.XMLHTTP");
9 }
因为所有现代浏览器和 IE 高版本浏览器都支持 XMLHttpRequest 对象,所以在创建对象时,也就不用做兼容性处理了,这里只是了解一下。在 IE 浏览器中 ActiveX 是插件的意思,也就是说 IE6 中的 AJAX 是通过一个插件来完成的,虽说是插件,但是在 IE6 浏览器中已经默认安装了。
在上面的代码中,在做判断时使用了 window.XMLHttpRequest ,我们都知道全局变量是 window 上的一个属性,在 JS 中,如果使用没有定义的变量,会报错,比如:alert(a)。而如果使用没有定义的属性,则不会报错,而是 undefined,比如:alert(window.a)。IE6 不支持 XMLHttpRequest,所以如果直接使用,就会报错,而如果把他定义为 window 的属性,那么则是 undefined ,未定义在 if 判断语句中代表假,也就是 fasle,而这正是我们需要的。
5、连接服务器
将请求发送到服务器,我们使用 XMLHttpRequest 对象的 open() 和 send() 方法:
oAjax.open('GET', 'ajax/demo.txt', true);
oAjax.send();
open(method, url, async) 规定请求的类型、URL 以及是否异步处理请求。第一个参数 method,用于规定请求的类型,GET 或 POST 。第二个参数 URL,用于设置文件在服务器上的地址,该文件可以是任何类型的文件,比如 .txt 、 .xml 和 .json,或者服务器脚本文件,比如 .php (在传回响应之前,能够在服务器上执行任务)。第三个参数 async,用于定义是否异步传输,true(异步)或 false(同步)。
send(string) 用于将请求发送到服务器,参数 string 仅用于 POST 请求。
下面来看两个问题。
(1)、GET 还是 POST?
GET 和 POST 常用于提交表单,我们也并不陌生,表单的提交默认是使用 GET 方式。
与 POST 相比,GET 更简单也更快,并且在大部分情况下都能用。
但是,在以下情况中,请使用 POST 请求:
①、无法使用缓存文件(更新服务器上的文件或数据库)。
②、向服务器发送大量数据(POST 没有数据量限制)。
③、发送包含未知字符的用户输入时,POST 比 GET 更稳定也更可靠。
最实用的判断方法:GET 用于获取数据,比如浏览贴子,POST 用于上传数据,也就是向服务器传递数据,比如用户注册。
GET 和 POST 的区别:
GET:在 URL 中传输数据,安全性弱,容量小,一般 URL 的长度最大为 4K 到 10K,长度是有限制的。
POST:不在 URL 中传输数据,相对安全性强,容量大,容量可达到2G,再大就可以使用控件,真正的安全就只有 https 协议。
缓存:GET 有缓存,POST 没有缓存。
所以,AJAX 一般都为 GET 方式。当然除了 GET 和 POST 方法之外还有很多种方法,最常用的还是这两种。
在 AJAX 基础的实例中,因为我们使用了 GET 请求,那么还有一个问题就是缓存的问题,所谓缓存,就好比一个网站打开一次之后,再打开的话,速度就会快一些,这就得益于缓存,那么缓存实际上就是一个网站,在第一次打开的时候,才是真正的从服务器上请求,之后都是从本地读取,从硬盘中读取数据肯定要快一些,至少比网络要快很多。那按照这样说,缓存岂不是个好东西,还有什么问题呢?我们来看一下 AJAX 中的实例,我们打开过一次了,也就是说已经有了本地缓存,那么如果这时候给 TXT 文件再加入一些文字,会如何呢?会发现点击按钮后,添加进去的文字不显示,过一会才显示,这就是缓存的问题,Chrome 和 FF 缓存还不严重,IE 浏览器的缓存比较严重。这个问题在很多时候会给我们带来一些困扰,比如是一个股票网站,需要实时更新最新的股票价格,这个价格一直在变,如果不阻止缓存,那么这个价格就很难做到实时更新,所以如果是时常在变的数据,就需要把缓存阻止掉。缓存的工作原理是根据 URL 来缓存的,同一个地址读取一次,因此要阻止缓存,只要让 URL 一直在变,也就是向 URL 添加一个唯一的 ID 。
我们平时在浏览网页时,都见过这种样子,比如在使用百度搜索时,百度域名后边跟了个问号,然后是一堆什么等于什么:百度安全验证前端&rsv_spt=1&rsv_iqid=0xe9146bd400052360&issp=1&,这个问号后边的数据就被称为 GET 数据。如果我们给 TXT 文件后边也加入 GET 数据,http://abc.com/ajax/demo.txt?a=2,或者可以自定义什么等于什么,这样对文件的显示内容是没有任何影响的,那么对于缓存的问题,我们就可以对 oAjax.open('GET', '/ajax/demo.txt', true) 第二个参数 URL 做一些修改,'ajax/demo.txt?t=' + Math.random(),Math.random() 方法返回一个 0-1 之间的随机小数,那么每次返回的都不同,也可以添加 'ajax/demo.txt?t=' + new Date().getTime(),getTime()用于获取当前的时间戳,也就是 1970年元旦 到当前的毫秒数,那么使用 get Time() 返回的数据每一次都不一样,因为是毫秒数,所以 1秒 之内就有很多种可能,他的值一直在变,这样就能很好的解决缓存问题。
这里要注意的是,在使用 GET 请求时,为了避免只是得到缓存的结果,需要向 URL 添加一个唯一的 ID,使 URL 每次都不一样。
如果需要通过 GET 方法发送信息,可以把信息添加在 URL 中。
如果需要像 HTML 表单那样传输 POST 数据,可以使用 setRequestHeader() 来添加 HTTP 头,然后在 send() 方法中规定发送的数据。
setRequestHeader(header, value) 用于向请求添加 HTTP 头,第一个参数 header 规定头的名称,比如 Content-type,第二个参数规定头的值。
(2)、true 还是 false?
同步和异步,在现实生活中,同步的意思为多件事一起做,而异步为一件件来,也就是不同步。但是在 JS 中同步和异步的概念和现实生活中恰恰是相反的,同步的意思为事情一件件来,先干完一件事再干另一件事,而异步则为多个事情可以一起做,而 AJAX 天生就是用来做异步操作的,如果 AJAX 工作在同步的方式下,也就是事情得一件一件来,当发出一个请求后,因为网速有点慢,这个请求在1分钟后才得到响应,那么在这个请求结束之前,页面中所有的按钮、链接、文字等全都跟死了一样,就完全没法操作了。而如果是异步的话,就没问题了,比如你发微博,发出去之后因为网速慢没有更新过来,那么在他更新之前,还可以做其他操作。
AJAX 指的是异步 JavaScript 和 XML(Asynchronous JavaScript and XML),XMLHttpRequest 对象如果要用于 AJAX 的话,其 open() 方法的 async 参数必须设置为 true,所以 AJAX 一般都为异步传输。对于 Web 开发者来说,发送异步请求是一个巨大的进步,很多在服务器执行的任务都相当费时,在 AJAX 出现之前,这可能会引起应用程序挂起或者停止。
而通过 AJAX,JS 无需等待服务器的响应,而是在等待服务器响应时执行其他脚步,当响应就绪后对响应进行处理。
当使用异步时,也就是 async = true 时,必需规定在响应处于 onreadystatechange 事件中的就绪状态时执行的函数:
1 oAjax.onreadystatechange = function (){
2 if(oAjax.readyState == 4 && oAjax.status == 200){
3 alert(oAjax.responseText);
4 }
5 }
6
7 oAjax.open('GET', 'ajax/demo.txt?t=' + Math.random(), true);
8 oAjax.send();
如需使用 async = false,请将 open() 方法中的第三个参数改为 false 。
不推荐使用同步传输,但是对于一些小型的请求,也是可以的。
这里需要注意,JS 会等到服务器响应就绪才继续执行,如果服务器繁忙或缓慢,应用程序会挂起或停止。
当使用 async = false 时,可以不用编写 onreadystatechange 函数,把代码放到 send() 语句后面即可:
1 oAjax.open('GET', 'ajax/demo.txt', false);
2 oAjax.send();
3 document.getElementById('div1').innerHTML = oAjax.responseText;
6、服务器响应
XMLHttpRequest 对象的 responseText 或 responseXML 属性用于获得来自服务器的响应,也就是获取从服务器返回的信息。
如果来自服务器的响应是 XML,而且需要作为 XML 对象进行解析,就使用 responseXML 属性。
如果来自服务器的响应并非 XML,就使用 responseText 属性,该属性返回字符串形式的响应,因此可以直接使用:
document.getElementById('div1').innerHTML = oAjax.responseText;
这里说到 XML ,我们就不得不提一下 AJAX 数据,也就是数据类型,数据类型可以分为很多种,比如中文、英文、数字等,我们经常使用的 JSON,他就是一种轻量级的数据交换格式。XML 相对来说那就是一个古老的存在,基本上都是在一些老式的程序中使用,都会从 XML 中读取数据,现在可以说是要被淘汰了,现在的程序几乎都是使用 JSON,因为同等数据量的情况下,XML 要比 JSON 大很多,这样会浪费带宽,浪费服务器资源,所以在使用 AJAX 获取从服务器返回的信息时,一般都使用 responseText 这个属性。
7、请求状态监控
XMLHttpRequest 对象的 readyState 属性返回请求的当前状态。当请求被发送到服务器时,我们需要执行一些基于响应的任务,每当 readyState 改变时,就会触发 onreadystatechange 事件,readyState 属性存有 XMLHttpRequest 的状态信息。
XMLHttpRequest 对象的三个重要的属性:
onreadystatechange:存储函数(或函数名),每当 readyState 属性改变时,就会调用该函数。
readyState:存有 XMLHttpRequest 的状态。从 0 到 4 发生变化。
0:请求未初始化。还没有调用 open() 方法。
1:服务器连接已建立,也就是载入。已调用 open() 方法,正在发送请求。
2:请求已接收,载入完成。open() 方法完成,已收到全部响应内容。
3:请求处理中,也叫解析。正在解析响应内容。
4: 请求已完成,且响应已就绪。响应内容解析完成,可以在客户端调用了。
status:请求结果,也就是 HTTP 状态码。200:OK。404:未找到页面。
100——客户必须继续发出请求
101——客户要求服务器根据请求转换HTTP协议版本
200——交易成功
201——提示知道新文件的URL
202——接受和处理、但处理未完成
203——返回信息不确定或不完整
204——请求收到,但返回信息为空
205——服务器完成了请求,用户代理必须复位当前已经浏览过的文件
206——服务器已经完成了部分用户的GET请求
300——请求的资源可在多处得到
301——删除请求数据
302——在其他地址发现了请求数据
303——建议客户访问其他URL或访问方式
304——客户端已经执行了GET,但文件未变化
305——请求的资源必须从服务器指定的地址得到
306——前一版本HTTP中使用的代码,现行版本中不再使用
307——申明请求的资源临时性删除
400——错误请求,如语法错误
401——请求授权失败
402——保留有效ChargeTo头响应
403——请求不允许
404——没有发现文件、查询或URl
405——用户在Request-Line字段定义的方法不允许
406——根据用户发送的Accept拖,请求资源不可访问
407——类似401,用户必须首先在代理服务器上得到授权
408——客户端没有在用户指定的饿时间内完成请求
409——对当前资源状态,请求不能完成
410——服务器上不再有此资源且无进一步的参考地址
411——服务器拒绝用户定义的Content-Length属性请求
412——一个或多个请求头字段在当前请求中错误
413——请求的资源大于服务器允许的大小
414——请求的资源URL长于服务器允许的长度
415——请求资源不支持请求项目格式
416——请求中包含Range请求头字段,在当前请求资源范围内没有range指示值,请求也不包含If-Range请求头字段
417——服务器不满足请求Expect头字段指定的期望值,如果是代理服务器,可能是下一级服务器不能满足请求
500——服务器产生内部错误
501——服务器不支持请求的函数
502——服务器暂时不可用,有时是为了防止发生系统过载
503——服务器过载或暂停维修
504——关口过载,服务器使用另一个关口或服务来响应用户,等待时间设定值较长
505——服务器不支持或拒绝支请求头中指定的HTTP版本
在 onreadystatechange 事件中,我们规定当服务器响应已做好被处理的准备时所执行的任务。
当 readyState 等于 4 且状态为 200 时,表示响应已就绪:
1 oAjax.onreadystatechange = function (){
2 if(oAjax.readyState == 4 && oAjax.status == 200){
3 alert(oAjax.responseText);
4 }
5 }
这里要注意: onreadystatechange 事件被触发 5 次(0 - 4),对应着 readyState 的每个变化。
如果网站中存在多个 AJAX 任务,那么就可以使用回调函数,回调函数是一种以参数形式传递给另一个函数的函数,应该为创建 XMLHttpRequest 对象编写一个标准的函数,并为每个 AJAX 任务调用该函数。
该函数调用应该包含 URL 以及发生 onreadystatechange 事件时执行的任务(每次调用可能不尽相同):
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="UTF-8"> 5 <title>AJAX 实例</title> 6 <script> 7 var oAjax;
8 function ajax(url, fnSucc){
9 oAjax = new XMLHttpRequest();
10
11 oAjax.onreadystatechange = fnSucc;
12
13 oAjax.open("GET", url, true);
14 oAjax.send();
15 }
16 function myFunction(){
17 ajax('ajax/demo.txt?t=' + Math.random(), function (){
18 if(oAjax.readyState == 4 && oAjax.status == 200){
19 alert(oAjax.responseText);
20 }
21 });
22 }
23 </script>
24 </head>
25 <body>
26 <button type="button" οnclick="myFunction()">读取</button>
27 </body>
28 </html>
8、AJAX 原理
AJAX 的原理就跟现实生活中给朋友打电话是一样一样的,首先,你得有个手机,不然拿什么打,也就是要有一个设备,当然现在那都是人手一部,这第一步就可以忽略了,然后就是拨号,所谓的拨号,就是把彼此的手机连接起来,建立一条通道,然后才能通信,如果接通了,就可以进行第三步了,那就是说,我们给别人打电话,肯定是要先说,然后再听对方说,那么最后就是听对方说,不可能是自己说完啪挂了,至少得听对方说点啥,也就是有个响应。
打电话需要4个步骤完成,其实我们在编写 AJAX 时,也是需要4个步骤,首先,就得创建 AJAX 对象,有了这个对象之后,才能进行下面的操作,那么接下来要做的就是连接到服务器,就相当于打电话拨号,连接到服务器之后,你就得主动告诉服务器你需要什么文件,不可能是服务器丢给你几个文件,你自己选,要不是了再给你换一批,不可能这样,再说那服务器都是给成千上万人提供服务,不可能去跟你在那玩你猜我猜猜不猜,所以我们就得明确的告诉服务器我们要哪个文件,那么第三步就是发送请求,最后一步就是接收返回值,获得服务器的响应,也就是把我们需要的那个文件给我们传回来。
我们平时都说 AJAX,其实这只是一个对外的称呼,真正在浏览器内部是通过 XMLHttpRequest 对象来完成 AJAX 请求的,这才是 AJAX 真正的对象。
下面我们看一下,根据这4个步骤,AJAX 代码的具体编写过程:
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="UTF-8"> 5 <title>AJAX 原理</title> 6 <script> 7 window.onload = function (){
8 var oBtn = document.getElementById('btn1');
9 oBtn.onclick = function (){
10 // 1、设备 = 创建 AJAX 对象11 var oAjax = new XMLHttpRequest();
12 // 创建好对象之后,就可以弹出来看一下。返回:[object XMLHttpRequest]13 // IE7 和 IE5 返回:[object]14 //alert(oAjax);15
16 // 在刚创建 AJAX 对象,还没调用 open() 方法,也就是请求未初始化时,弹出 readyState 状态。17 //alert(oAjax.readyState); // 返回:018
19 // 2、拨号 = 连接服务器20 oAjax.open('GET', 'ajax/demo.txt?t=' + new Date().getTime(), true);
21
22 // 3、说 = 发送请求23 oAjax.send();
24
25 // 4、听 = 接收返回26 oAjax.onreadystatechange = function (){
27 // oAjax.readyState 浏览器和服务器进行到哪一步了28 if(oAjax.readyState == 4) // 请求已完成29 if(oAjax.status == 200){ // 成功30 // 如果成功了,则弹出服务器响应的文本31 alert('成功 ' + oAjax.responseText);
32 }
33 else{
34 // 如果失败了,则弹出请求结果。35 alert('失败 ' + oAjax.status);
36 }
37 };
38 };
39 };
40 </script>41 </head>42 <body>43 <button type="button" id="btn1">读取</button>44 </body>45 </html>
上面的代码,在进行最后一步时,判断浏览器和服务器进行到哪一步了,当 readyState 属性状态为4时,就是请求完成了,但是请求完成并不代表请求成功,如果读取出错了或者文件不存在等情况导致出错了,那么也算是请求完成了,也就是不管读取成功还是失败,都算是请求完成了,所以需要进一步使用 status 属性判断,若为200,就是成功了。使用自定义的个人站点打开上面的 demo,点击按钮后,弹出成功和文本中的内容,我们可以试着改变一下 URL,就是把他故意写错,再次点击按钮,则会弹出失败和404,也就是未找到页面。
如果每次我们按照这4个步骤编写 AJAX(封装函数) 程序,是非常方便的,也容易理解,但是使用起来比较麻烦,所以我们可以把他封装为一个函数,在使用时调用就好使多了。
1 function ajax(url, fnSucc, fnFaild){
2 var oAjax = new XMLHttpRequest();
3 oAjax.open('GET', url, true);
4 oAjax.send();
5 oAjax.onreadystatechange = function(){
6 if(oAjax.readyState == 4){
7 if(oAjax.status == 200){
8 fnSucc(oAjax.responseText);
9 }
10 else{
11 if(fnFaild){
12 fnFaild(oAjax.status);
13 }
14 }
15 }
16 };
17 }
上面封装的 ajax 函数有三个参数,第一个参数 url,是文件路径,第二个参数 fnSucc,当每次成功的时候调用函数,第三个参数 fnFaild,当失败时调用的函数。这里并不是任何情况下都需要失败时执行一个函数,所以需要做一个判断,只有当 fnFaild 这个参数传入进来,也就是定义了失败时执行的函数,那么这时候才去调用他。
可以在 www 根目录中新建一个文件夹命名为 js,然后把上边的代码复制另存为 ajax.js,下面是封装好之后的应用:
1 <script src="js/ajax.js"></script>
2 <script>
3 window.onload = function (){
4 var oBtn = document.getElementById('btn1');
5 oBtn.onclick = function (){
6 ajax('ajax/demo.txt?t=' + new Date().getTime(), function (str){
7 alert('成功 ' + str);
8 }, function (){
9 alert('失败');
10 });
11 };
12 };
13 </script>
我们要从服务器读取 demo.txt 这个文件,目的是为了获取这个文件中的内容,那么如何获取返回的结果呢?当成功的读取信息后,要调用 fnSucc 这个参数,也就是成功后执行的回调函数,他其实是有一个参数的 str,这个参数可以自定义,str 的作用就是把服务器返回给我们的内容传入进来,这个 str 参数就是 fnSucc(oAjax.responseText) 中传过来的。
当失败的时候,调用 fnFaild 这个参数,也就是失败后执行的回调函数。那么这个失败时调用函数也是有一个参数的,fnFaild(oAjax.status),为了方便调试,我们也可以给他传入一个参数进来,用来提示请求失败的结果。在真正的网站中,当 AJAX 请求失败时,也不可能弹一个 alert,这样不太友好,所以可以自定义一些更加友好的方式来提示用户。这里建议大家平时在调试 AJAX 程序时,一定要加上失败时执行的回调函数,否则如果失败的话,那么可能没有任何反应。
9、AJAX 应用
请求一个静态的 TXT 文件,在了解了 AJAX 的原理后,很容易的就可以做到,但是在真正的网站中,这样不会有太大的实际用途,前边我们说 AJAX 是一种与服务器交换数据并更新部分网页的艺术,那么既然称之为艺术,因此我们需要使用 AJAX 去请求一些更实用、更复杂的东西,这样才能完美的体现他存在的价值。比如可以去请求动态数据,或者去请求一个装着数据的 JSON 文件。
(1)、读取数组
首先,新建一个 TXT 文件命名为 arr.txt,随意存一个数组,比如[1,2,3,4,5,6],放在之前的 ajax 文件夹下,然后就可以开始编写程序了。
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="UTF-8"> 5 <title>AJAX 读取数组</title> 6 <script src="js/ajax.js"></script> 7 <script> 8 window.onload = function (){
9 var oBtn = document.getElementById('btn1');
10 oBtn.onclick = function (){
11 ajax('ajax/arr.txt?t=' + new Date().getTime(), function (str){
12
13 // str 是服务器返回的内容,弹出来看一下14 //alert(str); 返回:[1,2,3,4,5,6]15
16 // 那么再弹出内容的长度17 //alert(str.length); // 返回:1318
19 // 返回对象的类型:string20 //alert(typeof str);21
22 // eval() 函数用于把字符串转换为 JS 代码执行23 //alert(eval(str)); // 返回:1,2,3,4,5,624
25 // 现在可以返回内容的长度26 //alert(eval(str).length); // 返回:627
28 // 可以把这个函数保存为变量,查看每项的值29 var arr = eval(str);
30 alert(arr[1]); // 返回:231
32 }, function (){
33 alert('失败');
34 });
35 };
36 };
37 </script>38 </head>39 <body>40 <button type="button" id="btn1">读取</button>41 </body>42 </html>
上面的实例中,str 是服务器返回给我们的内容,弹出来之后,是我们定义的数组,没有问题,那么弹出数组的长度,却返回 13,数组的长度本应该是 6 啊,怎么会是 13 呢,我们再弹出这个对象的类型,结果返回 string,尽管他长的很像数组,但他确实是一个字符串,这是为什么呢?其实通过 AJAX 的方式读取的任何对象都是以字符串形式存在的,那么这个字符串的长度就应该是13,方括号加上标点。如果要把一个字符串中存的数组提取出来,就要使用 eval(string) 函数,该函数可计算某个字符串,并把他作为 JavaScript 代码来执行,也就是可以把一个语句中的内容解析为 JS 可以识别的语句,该方法只接受原始字符串作为参数,如果 string 参数不是原始字符串,那么该方法将不作任何改变地返回。那么使用该方法之后再次返回数组的内容和长度,就没有问题了。我们也可以把这个函数保存在一个变量中,来查看每项的值。虽然 eval() 的功能非常强大,但在实际使用中用到他的情况并不多。
(2)、读取 JSON 数据
首先,还是需要新建一个 JSON 文件,可以命名为 json.json,可以随意存入一个数组对象,比如[{a:9, b:6, c:15}, {a:5, b:7, c:12}],然后放在 ajax 文件夹下,最后开始编写程序。
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="UTF-8"> 5 <title>AJAX 读取JSON</title> 6 <script src="js/ajax.js"></script> 7 <script> 8 window.onload = function (){
9 var oBtn = document.getElementById('btn1');
10 oBtn.onclick = function (){
11 ajax('ajax/json.json?t=' + new Date().getTime(), function (str){
12 var arr = eval(str);
13 // 返回数组的第0个元素,也就是数组对象中的第一项14 alert(arr[0]); // 返回:[object Object]15
16 // 返回第0个元素中第一项 a 的值17 alert(arr[0].a); // 返回:918 }, function (){
19 alert('失败');
20 });
21 };
22 };
23 </script>24 </head>25 <body>26 <button type="button" id="btn1">读取</button>27 </body>28 </html>
上面的实例,使用 eval() 函数解析出来之后,还是一个数组,返回数组的第0个元素,也就是 {a:9, b:6, c:15},他还是一个 JSON 数据,所以返回 obj,那么再返回第0个元素中 a 的值,可以看到,使用方法和读取数组的方法是一样的。那如果 JSON 中保存的数据更复杂一些,比如是一组用户信息,要如何去读取,然后并以列表形式显示在网页中呢?
下面是 JSON 用户信息数据,可以复制替换一下,这里在保存 JSON 时需要注意编码格式,一旦文件中出现中文了,就必须保存为 UTF-8 的格式,为了方便区分,我们可以把这个文件命名为 date.json 。
1 [
2 {
3 "user": "小白",
4 "sex": "男",
5 "age": 27
6 },
7 {
8 "user": "初夏",
9 "sex": "女",
10 "age": 23
11 },
12 {
13 "user": "小明",
14 "sex": "男",
15 "age": 25
16 },
17 {
18 "user": "静静",
19 "sex": "女",
20 "age": 21
21 }
22 ]
(3)、创建 DOM 元素显示 JSON 数据
1 <!DOCTYPE html>
2 <html>
3 <head>
4 <meta charset="UTF-8">
5 <title>AJAX 读取JSON</title>
6 <script src="js/ajax.js"></script>
7 <script>
8 window.onload = function (){
9 var oBtn = document.getElementById('btn1');
10 var oUl = document.getElementById('u1');
11 oBtn.onclick = function (){
12 ajax('ajax/date.json?t=' + new Date().getTime(), function (str){
13 var arr = eval(str);
14 //循环遍历返回的对象15 for(var i=0; i<arr.length; i++){
16 //每次循环的时候创建一个li元素17 var oLi = document.createElement('li');
18 //向li元素插入内容19 oLi.innerHTML = '姓名:<strong>' + arr[i].user + '</strong> 性别:<span>' + arr[i].sex + '</span> 年龄:<span>' + arr[i].age + '</span>';
20 //将创建好的li元素插入到ul中21 oUl.appendChild(oLi);
22 }
23 },function (){
24 alert('失败');
25 });
26 };
27 };
28 </script>
29 </head>
30 <body>
31 <input id="btn1" type="button" name="user" value="读取">
32 <!-- 点击按钮生成json数据列表 -->
33 <ul id="u1">
34 <!-- <li>姓名:<strong>小白</strong> 性别:<span>男</span> 年龄:<span>27</span></li> -->
35 </ul>
36 </body>
37 </html>
上面的代码,写起来也没什么难度,都是一些基础的知识,在浏览器打开自定义的个人站点,点击读取按钮之后,JSON 文件中存的数据,就会以为列表的形式显示在页面上,这里只是简单的做了一个效果,我们还可以给他定义样式,或者可以创建一个表格,让他更友好的显示。
这里在网上看到了一个方法,在处理 AJAX 请求得到 JSON 数据响应时,也就是服务器返回的 JSON 字符串,需要做一次对象化处理,可以不使用 eval() 方法,而是使用 new Function() 代替,新的 Function() 构造就类似于 eval(),或者使用 jQuery 提供的 $.getJSON() 方法获得服务器返回,那么就可以不使用 eval() 方法了。具体操作如下:
//var arr = eval(str);var arr = (new Function('', 'return' + str)());
此时的 arr 就会被解析成一个 JSON 对象了,然后再使用循环遍历,将数据插入到新建的 li 元素中。
10、AJAX 总结
这一章只是总结了一些 AJAX 最基础的知识,到这里,就可以使用 AJAX 做一些基本的应用了,但是 AJAX 不仅仅在于此,他有很多非常高大上而且很实际的应用,比如一些大型系统如何使用 AJAX 搭建,如何编写一套完整的 AJAX 交互程序,还有跨域,还有 JSONP 等,要想真正的掌握 AJAX 这门艺术,路还很长。