Ajax学习笔记

一、什么是Ajax

Ajax是Asynchronous Javascript and XML 的缩写,就是异步的JavaScript 和 XML,他是指一种创建交互式网页应用的网页开发技术。
主要包含的技术:

  1. 基于web标准(standrads-based presentation)XHTML + CSS的表示。
  2. 使用DOM(Document Object Model)进行动态显示及交互。
  3. 使用XML和XSTL进行数据传输及相关操作
  4. 使用XMLHttpRequest对象进行异步数据的查询,检索。
  5. 使用JavaScript将所有的东西绑定在一起。

二、Ajax的由来

异步主要解决的问题:更新网页中只需要更新的部分,而不是重新加载整个网页。

解决方案:

  1. 1995年,JAVA语言的第一版发布,随之发布的Java applets(Java 小程序)首次实现了异步加载,浏览器通过运行嵌入网页中的Java 小程序与服务器交换数据,不必刷新整个网页。

  2. 1996年,Internet Explorer将 iframe元素加入到HTML,支持局部刷新网页。

  3. 1998年前后,Outlook Web Access小组写成了允许客户端脚本发送HTTP请求(XMLHTTP)的第一个组件。并且迅速成为IE4.0的一部分。2005年,随着Google suggest、 Google map的发布,Ajax才广泛引起重视。
    2005年2月,AJAX这个词第一次正式提出,指围绕这个功能进行开发的一整套做法。从此,AJAX成为脚本发起HTTP通信的代名词,W3C也在2006年发布了它的国际标准。

三、Ajax的原理

在看ajax原理之前,我们先来看传统的web交互方式。
Ajax学习笔记_第1张图片
在旧的交互方式中,由用户触发一个HTTP请求到服务器,服务器对其进行处理后在返回一个新的HTML页面到客户端,每当服务器处理客户端提交的请求时,用户都是处于等待状态,并且哪怕只是一次很小的交互、只需从服务器端得到很简单的一个数据,都要返回一个完整的HTML页面,而用户每次都要浪费时间和带宽去重新读取整个页面。而使用Ajax后用户从感觉上几乎所有的操作都会很快响应没有页面重载(白屏)的等待。

Ajax交互方式
Ajax学习笔记_第2张图片
Ajax的工作原理相当于在用户和服务器之间加了一个中间层(Ajax引擎),使用户操作与服务器响应异步化,并不是所有的请求都提交给服务器,像一些数据验证和数据处理都交给Ajax引擎自已来做,只有确定需要从服务器读取新数据时再有Ajax引擎代向服务器提交请求。

在会话开始时,浏览器加载了一个Ajax引擎 - 用JavaScript编写,通常隐藏在一个隐藏的框架中,而不是加载网页。该引擎负责呈现用户看到的界面并代表用户与服务器进行通信。

Ajax引擎,实际上是一个比较复杂的JavaScript应用程序,用来处理用户请求,读写服务器和更改DOM内容。JavaScript的Ajax引擎读取信息,并且互动地重写DOM,这使网页能无缝化重构,也就是在页面已经下载完毕后改变页面内容,这是我们一直在通过JavaScript和DOM在广泛使用的方法,但要使网页真正动态起来,不仅要内部的互动,还需要从外部获取数据,在以前,我们是让用户来输入数据并通过DOM来改变网页内容的,但现在,XMLHTTPRequest,可以让我们在不重载页面的情况下读写服务器上的数据,使用户的输入达到最少。

Ajax使WEB中的界面与应用分离(也可以说是数据与呈现分离)【并不是十分理解这句话】,而在以前两者是没有清晰的界限的,数据与呈现分离的分离,有利于分工合作、减少非技术人员对页面的修改造成的WEB应用程序错误、提高效率、也更加适用于现在的发布系统。也可以把以前的一些服务器负担的工作转嫁到客户端,利于客户端闲置的处理能力来处理。

4、构建Ajax应用的具体实现

  1. 创建Ajax请求对象
  2. 初始化请求对象
  3. 发出HTTP请求
  4. 接收服务器传回来的数据
  5. 利用回调函数,更新网页数据。

概括起来,就是一句话,Ajax通过原生的XMLHttpRequest对象发出HTTP请求,得到服务器返回的数据后,再利用回调函数进行处理。

一旦拿到服务器返回的数据,Ajax不会刷新整个网页,而是只更新相关部分,从而不打断用户正在做的事情。

window.onload = initPage;

function initPage() {
    username = document.getElementById("username");
    register = document.getElementById("register");
    username.onblur = checkUsername;
    register.disabled = true;
}
//异步去服务器验证用户名是否未被占用
function checkUsername() {
    username.className = "thinking";
    //创建请求对象
    request = createRequest();
    if(request == null) {
        alert("Unable to create request!");
    } else {
        var theName = username.value;
        var usernameValue = escape(theName);
        var url = "checkName.php?username=" + usernameValue;
        //指定回调函数
        request.onreadystatechange = showUsernameStatus;
        //初始化请求对象
        request.open("GET",url,true);
        //发送请求对象
        request.send(null);
    }
}
//利用回调函数,通过返回更新页面数据。
function showUsernameStatus() {
    if(request.readyState == 4) {
        if(request.status == 200) {
            if(request.responseText == "okey") {
                username.className = "approved";
                register.disabled = false;
            } else {
                username.className = "denied";
                username.focus();
                username.select();
                register.disabled = true;
            }
         }
    }
}

XMLHttpRequest对象用来在浏览器和服务器之间传输数据。

兼容性获取XMLHttpRequest的方法

function createRequest() {
  try {
    request = new XMLHttpRequest();
  } catch (tryMS) {
    try {
      request = new ActiveXObject("Msxml2.XMLHTTP");
    } catch (otherMS) {
      try {
        request = new ActiveXObject("Microsoft.XMLHTTP");
      } catch (failed) {
        request = null;
      }
    }
  } 
  return request;
}
XMLHttpRequest实例的属性

1、readyState是一个只读属性,表示XMLHttpRequest请求对象当前所处的状态,每次发生状态改变时,readyState属性的值就会发生改变。这个值每一次变化,都会触发readystatechange事件,从而调用请求对象的onreadystatechange属性指定的回调函数。

几种取值说明:
0:未初始化状态:此时,已经创建了一个XMLHttpRequest对象,但是还没有初始化,就是还没有调用open()方法;

1:准备发送状态:此时已经调用了XMLHttpRequest对象的open()方法,并且XMLHttpRequest对象已经准备好将一个请求发送到服务器端。

2:已经发送状态:此时,已经通过send()方法把一个请求发送到服务器端,但是还没有收到一个响应。

3:正在接受状态:此时,已经接受到HTTP响应的头部信息

4:完成响应状态(DONE):完成响应状态:此时,已经完成了HttpResponse响应的接收,或者本次响应接收失败了。

注意点:如果使用abort() 方法终止XMLHttpRequest请求,onreadystatechange回调函数也会被调用。

2、response:是一个只读属性,表示接收到的数据体(即就是body部分);

3、responseType:用来指定服务器返回数据的(request.response)的类型。

text类型适合大多数情况,而且直接处理文本也比较方便,document类型适合返回XML文档的情况,blob类型适合读取二进制数据,比如图片文件。

4、responseText:是一个只读属性,返回从服务器接收到的字符串,如果本次请求没有成功或者数据不完整,该属性为null。
如果服务器返回的数据格式是JSON,就可以使用responseText属性。

5、responseXML:是一个只读属性,返回从服务器接收到的Document对象,如果本次请求没有成功,或者数据不完整,或者不能被解析为XML或HTML,该属性等于null。

返回的数据会被直接解析成DOM对象。

6、status:只读属性,表示本次请求所得到的HTTP状态码,是一个整数,一般来说,如果通信成功,就会返回200;
基本上,只有2xx和304(Not Modified)状态码,表示服务器返回是正常状态。

if(request.readyState == 4) {
    if ((request.status >= 200 && request.status < 300) || (request.status == 304)) {
        //Handle the response
    } else {
        //error
    }

}

7、statusText:是一个只读属性,返回一个字符串,表示服务器发送的状态提示,
与status不同的是,该属性包含整个状态信息,比如 ” 200 OK”;

8、timeout:属性等于一个整数,表示多少毫秒之后,如果请求仍然没有得到结果,就会自定终止,如果该属性等于0,就表示没有时间限制(默认情况下就是0)。

withCredentials:属性是一个布尔值,表示跨域请求时,用户信息(比如Cookie和认证的HTTP头信息)是否会包含在请求之中,默认为false。即向example.com发出跨域请求时,不会发送example.com设置在本机上的Cookie(如果有的话)。
如果需要通过跨域Ajax发送Cookie,需要打开withCredentials。

request.withCredentials = true
XMLHttpRequest实例的方法

1、abort() 用来终止已经发出的HTTP请求。

2、getAllRespnsetHeaders():用来返回服务器响应的所有HTTP头信息,格式为字符串,每个信息之间使用CRLF分隔,如果没有收到,该属性返回null。

3、getResponseHeader():用来返回HTTP头信息指定字段的值,如果还没有收到服务器回应或者指定字段不存在,则该属性为null。

4、open() :XMLHttpRequest对象的open方法用于指定发送HTTP请求的参数(即就是用来初始化一个请求对象),它的使用格式如下,一共可以接受五个参数。

request.open(
    string method, //HTTP动词:如"GET" "POST"
    string url, //表示请求要发送的网址
    optional boolean async, //表示是否异步
    optional string user, //表示用于认证的用户名,默认为空字符串。
    optional string password //表示用于认证的密码,默认为空字符串。
);

如果对使用过open()方法的请求,再次使用这个方法,等同于调用abort()

5、send():用于实际发出HTTP请求。如果不带参数,就表示HTTP请求只包含头信息,也就是只有一个URL,典型例子就是GET请求;如果带有参数,就表示除了头信息,还带有包含具体数据的信息体,典型例子就是POST请求。“

var url = "checkName.php?username=" + usernameValue;
        request.onreadystatechange = showUsernameStatus;
        request.open("GET",url,true);
        request.send(null);

var url = "checkName.php";
var data = username=" + usernameValue;
        request.onreadystatechange = showUsernameStatus;
        request.open("GET",url,true);
        request.send(data);

这两段代码的作用是等同的,GET请求的参数可以作为查询字符串加在URL的后面,也可以作为send方法的参数。

注意点,所有的XMLHttpRequest的监听事件,都必须都在send()方法调用之前设定。

6、setRequestHeader():用于设置HTTP头信息,该方法必须在open()之后,send()之前调用。
7、overrideMimeType() 该方法用来指定服务器返回数据的MIME类型。该方法必须在send()之前调用。
传统上,如果希望从服务器取回二进制数据,就要使用这个方法,人为将数据类型伪装成文本数据。

五、Ajax优缺点:

优点
  1. 无刷新更新数据:Ajax最大的优点就是能在不刷新整个网页的前提下与服务器通信维护数据,这使得web应用程序更为迅速地响应用户的交互,避免了在网络上发送哪些没有改变的信息(因为不会加载整个网页),减少了用户等待时间,用户体验非常好。
  2. 异步与服务器通信:Ajax使用异步的方式与服务器通信,不会打断用户的操作,具有更加迅速的响应能力,优化了Browser和Server之间的沟通,减少不必要的数据传输、时间及降低网络上数据流量。
  3. 前端和后端负载平衡:可以把以前一些服务器负担的工作转嫁到客户端,利用客户端闲置的能力来处理,减轻服务器和带宽的负担,节约空间和宽带租用成本。并且减轻服务器的负担,ajax的原则是“按需取数据”,可以最大程度的减少冗余请求,和响应对服务器造成的负担。
  4. 基于标准被广泛支持:Ajax是基于标准化并被广泛支持的技术,不需要下载浏览器插件或者小程序,但需要用户未在浏览器中禁用JavaScript。
  5. 界面与应用分离:Ajax使WEB中的界面与应用分离(也可以说是数据与呈现分离),有利于分工合作、减少非技术人员对页面的修改造成的WEB应用程序错误、提高效率、也更加适用于现在的发布系统。
缺点:
  1. AJAX干掉了Back和History功能,即对浏览器机制的破坏。
    在动态更新页面的情况下,用户无法回到前一个页面状态,因为浏览器仅能记忆历史记录中的静态页面。一个被完整读入的页面与一个已经被动态修改过的页面之间的差别非常微妙;用户通常会希望单击后退按钮能够取消他们的前一次操作,但是在Ajax应用程序中,这将无法实现。
    后退按钮是一个标准的web站点的重要功能,但是它没法和js进行很好的合作。这是Ajax所带来的一个比较严重的问题,因为用户往往是希望能够通过后退来取消前一次操作的。那么对于这个问题有没有办法?答案是肯定的,用过Gmail的知道,Gmail下面采用的Ajax技术解决了这个问题,在Gmail下面是可以后退的,但是,它也并不能改变Ajax的机制,它只是采用的一个比较笨但是有效的办法,即用户单击后退按钮访问历史记录时,通过创建或使用一个隐藏的IFRAME来重现页面上的变更。(例如,当用户在Google Maps中单击后退时,它在一个隐藏的IFRAME中进行搜索,然后将搜索结果反映到Ajax元素上,以便将应用程序状态恢复到当时的状态。)
    但是,虽然说这个问题是可以解决的,但是它所带来的开发成本是非常高的,并与Ajax框架所要求的快速开发是相背离的。这是Ajax所带来的一个非常严重的问题。
    一个相关的观点认为,使用动态页面更新使得用户难于将某个特定的状态保存到收藏夹中。该问题的解决方案也已出现,大部分都使用URL片断标识符(通常被称为锚点,即URL中#后面的部分)来保持跟踪,允许用户回到指定的某个应用程序状态。(许多浏览器允许JavaScript动态更新锚点,这使得Ajax应用程序能够在更新显示内容的同时更新锚点。)这些解决方案也同时解决了许多关于不支持后退按钮的争论。
  2. Ajax的安全问题:Ajax技术给用户带来很好的用户体验的同时也对IT企业带来了新的安全问题,Ajax技术就如同对企业的数据建立了一个直接通道。
  3. 违背URL和资源定位的初衷:我给你一个URL,如果采用Ajax技术,也许在该URL地址下你看到的页面和我看到的页面不一样。
  4. 移动设备不能很好的支持:用手机打开采用Ajax技术的网站时,目前是不支持的。
附《Head first Ajax》学习笔记

最近花了一周读完了这本书,一个字就是爽,感觉这和DOM编程艺术一样,都可以称之为经典。
以下是我认为书中比较重要的学习笔记总结:
1

参考链接

https://javascript.ruanyifeng.com/bom/ajax.html
https://web.archive.org/web/20061107032631/http://www.adaptivepath.com/publications/essays/archives/000385.php
http://www.cnblogs.com/SanMaoSpace/archive/2013/06/15/3137180.html
https://segmentfault.com/a/1190000006669043

你可能感兴趣的:(JavaScript,Ajax学习笔记总结)