06月07, 2019

Java Web--JS--AJAX

Ajax 编程

1999 年,微软公司发布 Internet Explorer 5,第一次引入新功能:允许 JavaScript 脚本向服务器发起 HTTP 请求。这个功能当时并没有引起人们太多的关注,直到 2004 年 Gmail 的发布以及 2005 年 Google Map 发布,才引起广泛重视。

2005 年 2 月,Ajax 这个词第一次正式提出,指围绕这个功能进行开发的一整套做法。从此,Ajax 成为脚本发起 HTTP 通信的代名词,W3C 也在 2006 年发布了它的国际标准。

本章我们将学习如下内容:

  • Ajax 基本介绍
  • Ajax 具体实现

一、Ajax 基本介绍

1. 什么是 Ajax

当万维网开始时,网页只包含静态内容。客户端和服务端之间传输数据都是通过 form 表单。在 Web 应用程序中,客户通过表单提交自己输入的信息,服务器端的程序接受到客户提交的表单后,根据表单的数据内容进行处理,然后把处理结果返回给用户,这样就完成了一个简单的交互。

但是这种数据传输方式有一个很大的缺陷,就是每次用户与服务器的交互都需要重新刷新整个页面。在那个网速不佳的年代,重新刷新页面的成本是很高的,通常会导致在加载页面时屏幕变空白。

1999 年,微软公司在 Internet Explorer 5 中实现了 XMLHttp ActiveX 控件。它最初是为 outlook Web 客户端而开发的,允许在后台使用 JavaScript 异步发送数据。随后其他浏览器也实现了这种技术,不过它仍然是一个相对未知的功能,很少使用。

2004 年和 2005 年,Google 公司相继推出了 Gmail 和 Google 地图。从这个时候开始,异步加载技术开始备受关注。这些 Web 应用程序使用的异步加载技术,通过更改页面部分内容而不进行全面刷新来增强了用户的体验。让用户感觉更像是一个桌面应用程序。

Ajax 这个术语是由 Jesse James Garrett 于 2005 年在"Ajax:一种新的 Web 应用程序方法"一文中所创造的,他提到了 Google 在其最近的 Web 应用程序中使用到的技术。Ajax 是一个简洁的首字母缩写词,指的是该技术在使用的过程中所涉及到的不同部分,全称:Asynchronous JavaScript and XML。

Asynchronous:翻译成中文是异步的意思,当发送数据请求时,程序不必停下来等待响应。它可以继续运行,等待响应收到时触发事件。通过使用回调来管理这种过程,程序能够以有效的方式运行,避免了数据来回传输带来的延迟。

JavaScript:利用 JavaScript 我们可以接收来自服务器端返回的数据,并将这些数据实时的更新到页面上。

XML:最开始术语 Ajax 被创造时,经常用 XML 文档来返回数据。但是实际上可以发送许多不同类型的数据。到目前为止,在 Ajax 中最常用的是 JSON,它比 XML 更轻量且更易于解析。JSON 还具备被 JavaScript 原生支持的优点,所以我们可以处理 JavaScript 对象,而不必使用 DOM 方法来解析 XML 文件。

在 Garrett 的文章发表以后,Ajax 的使用真正开始起飞。现在用户不必刷新页面,就可以在网页上看到新的内容。例如购物篮的数据在后台更新,但是页面上的内容却可以无缝加载,还有诸如动态加载照片库等。

基本上可以这么说,当需要网页部分页面更新时,不太可能不用 Ajax。公共 API 的爆炸式增长,也意味着 Ajax 比以往任何时候都更多地在站点之间来回传输数据。

Ajax 实现了与服务器的异步通信、局部刷新页面,这就是 Ajax 技术的核心所在。当然 Ajax 也不是只有优点没有缺点,关于 Ajax 的优缺点总结如下:

优点:

  • 页面无刷新,在页面内与服务器通信,减少用户等待的时间,增强了用户体验。

  • 使用异步方式与服务器通信,响应速度快。

  • 可以把一些原本服务器的工作转接到客户端,利用客户端闲置的能力来处理,减轻了服务器和宽带的负担,节约空间和宽带租用成本。

  • 基于标准化的并被广泛支持的技术,不需要下载插件或者小程序。

缺点

  • 无法进行操作的后退,即不支持浏览器的页面后退。

  • 对搜索引擎的支持比较弱。

  • 可能会影响程序中的异常处理机制。

  • 安全问题。对一些网站的攻击,如 CSRF,XXS,SQL 注入等不能很好的防御。

2. Ajax 实现原理

使用原生的 Ajax 大致包括以下几步骤:

1. 创建XMLHttpRequest对象 2. 发出HTTP请求 3. 接收服务器传回的数据 4. 更新网页数据

概括起来,就是一句话,Ajax 通过原生的 XMLHttpRequest 对象发出 HTTP 请求,得到服务器返回的数据后,再进行处理。下面我们通过一张图来解释 Ajax 的工作原理:

15460590515193

下面的图解释了 Ajax 和传统方式的区别,如下:

15460590782610

二、Ajax 具体实现

前面有介绍过,使用原生的 Ajax 大致包括以下几步骤:

1. 创建 XMLHttpRequest 对象 2. 发出 HTTP 请求 3. 接收服务器传回的数据 4. 更新网页数据

接下来我们来具体看一下每一个部分。

--

Ajax 技术的核心就是 XMLHttpRequest 对象(简称 XHR)。这是由微软首先引入的一个特性,是一种支持异步请求的技术。(后来其他浏览器开发商也都提供了相同的功能实现。)

简而言之,XMLHttpRequest 用于与服务器交换数据。这意味着用户操作页面后,可以不必刷新页面也能够取得新的数据。

1. 创建XMLHttpRequest对象

创建一个XMLHttpRequest对象,也叫实例化一个XMLHttpRequest对象。因为XMLHttpRequest()本身是一个构造函数。

let xhr = new XMLHttpRequest();

IE5 是第一款引入XMLHttpRequest对象的浏览器。在 IE5 和 IE6 中,XHR 对象是通过 MSXML 库中的一个 ActiveX 对象实现的。

let xhr = new ActiveXObject('Microsoft.XMLHTTP');

而 IE7+ 及其他标准浏览器都支持原生的XMLHttpRequest对象。为了应对所有浏览器,下面是创建XMLHttpRequest对象的兼容写法。

let xhr;
if(window.XMLHttpRequest){
    //  IE7+, Firefox, Chrome, Opera, Safari 浏览器执行代码
    xhr = new XMLHttpRequest();
} else {
    // IE6, IE5 浏览器执行代码
    xhr = new ActiveXObject( 'Microsoft.XMLHTTP' );
}

2. 打开连接

XMLHttpRequest的实例对象提供了一个open()方法用来打开客户端与服务端之间的连接。该方法规定了请求的类型、请求的路径以及是否异步处理请求。语法结构如下:

xhr.open(method, url, async);

参数说明:

method:发送请求的方式。取值有 GETPOST(不区分大小写,建议使用大写)。
url:请求资源的位置路径。
async:控制是否异步处理请求。取值有 true(异步)和 false(同步),默认为 true

一般来讲,都会产用异步的方式来发送请求,不然 Ajax 将变得毫无意义。

3. 发送请求

XMLHttpRequest的实例对象提供了一个send()方法用于客户端向服务端发送请求。

xhr.send();

请求参数

在向服务端发送请求的同时,是可以传递数据至服务端的。而请求方式的不同,数据的传递方式也不同。

GET 请求:传递的数据是跟在open()方法中的url后面。

xhr.open("GET","/users/isUser?username=zhangsan&pwd=123");
xhr.send(null);

POST 请求:传递的数据是放在send()方法的参数中。调用send()方法之前需要设定Content-Type头信息,模拟 HTTP 的 POST 方法发送一个表单,这样服务器才会知道如何处理上传的内容。

参数的提交格式和 GET 方法中url的写法一样。设置头信息前必须先调用open()方法。

xhr.open("POST","login.php",true);
xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded;charset=UTF-8");
xhr.send("username=zhangsan&pwd=123");

和 POST 相比,GET 的请求方式更简单也更快,并且在大部分情况下都能使用。但是,在以下情况中,请使用 POST 请求:

  1. 无法使用缓存文件(更新服务器上的文件或者数据库)
  2. 向服务器发送大量数据(POST 没有数据量的限制)
  3. 发送包含未知字符的用户输入时,POST 比 GET 更稳定也更可靠

4. 处理服务器返回的消息

一个完整的 HTTP 响应由状态码、响应头集合和响应主体组成。在收到响应后,可以通过 XHR 对象的属性来获取响应内容。常用的属性有以下 4 个:

responseText: 作为响应主体被返回的文本(文本形式)
responseXML: 如果响应的内容类型是 text/xml 或 application/xml,这个属性中将保存着响应数据的 XML DOM 文档(document 形式)
status: HTTP 状态码(数字形式)
statusText: HTTP 状态说明(文本形式)

另外,第 2 步打开连接时,选择处理请求的方式不同,第 4 步处理服务器返回消息的方式也有所不同。

同步处理请求

当处理请求的方式为同步时,直接使用XMLHttpRequest的实例对象的responseText属性用来接收服务端返回的消息。

xhr.responseText;

但是不推荐使用同步处理请求的方式。使用这种方式会导致 JavaScript 代码要一直等到服务器响应就绪后才继续执行,如果服务器繁忙或缓慢,应用程序就会挂起或停止。但是对于一些小型的请求,也是可以的。

异步处理请求

当处理请求的方式为异步时,需要通过XMLHttpRequest的实例对象提供的onreadystatechange事件来监听并处理服务器返回的消息。

xhr.onreadystatechange = function(){
    // ...
}

从“请求准备发送”到最后“请求发送成功”,中间执行了一系列的任务,分别为:

请求未初始化(0):即还没有调用 send() 方法;
服务器连接已建立(1):即已调用 send() 方法,正在发送请求;
请求已接收(2):即 send() 方法执行完成;
请求处理中(3):即正在解析响应内容;
请求已完成(4):且响应已就绪,即响应内容解析完成,可以在客户端进行调用了;

每执行一个任务,XMLHttpRequest对象的状态值readyState都会发生改变。只要readyState属性发生改变时,就会触发onreadystatechange事件。

按照任务顺序,状态值readyState依次从 0 到 4 发生改变。

只有当状态值为 4 时,才表示请求完成。请求完成后,判断请求状态,状态码status为 200 时表示请求成功。只有请求完成并且成功了,才能处理服务端返回的消息。

xhr.onreadystatechange = function(){
    if(xhr.readyState == 4 && xhr.status == 200){
        let text = xhr.responseText;
        console.log( text );
    }
}

5. 完整代码

我们将上面分解的每一步整合在一起,就是一个完整的 Ajax 请求代码了。

// 创建 XHR 对象
let xhr;
if (window.XMLHttpRequest) {
    //  IE7+, Firefox, Chrome, Opera, Safari 浏览器执行代码
    xhr = new XMLHttpRequest();
} else {
    // IE6, IE5 浏览器执行代码
    xhr = new ActiveXObject('Microsoft.XMLHTTP');
}

// 2. 打开连接
xhr.open("get", "/users/isPhoneExist?phone=12313212311"); // 第三个参数默认 true,表示异步;get 请求的参数跟在路径后面。

// 3. 发送请求
xhr.send(); // send 方法默认没有参数。
//xhr.send("phone=123&pwd=123");  // 请求是 post,且想要传参,send 方法才有参数。

// 4. 通过事件监听并处理服务器返回的消息
xhr.onreadystatechange = function () {
    if (xhr.readyState == 4 && xhr.status == 200) { // 服务器正常的响应数据回来
        let text = xhr.responseText;   // 得到的 text 是字符串
        // info.innerHTML = text;  // 处理响应数据
    }
}

总结

  1. Ajax 并不是一门崭新的技术,而是当时所存在的几种技术的结合。

  2. 使用原生 Ajax 的步骤大致可以分为:创建 XMLHttpRequest 对象,发出 HTTP 请求,接收服务器传回的数据和更新网页的数据。

  3. 根据浏览器的不同,创建 XMLHttpRequest 对象的方式也不同。

  4. 发送请求时要用到 open 方法和 send 方法。

  5. readyState 属性有 5 种状态值,一般我们只对值为 4 的时候采取相应的操作。

三、jQuery的ajax方法

jQuery 提供很多 Ajax 的方法,方便我们使用 Ajax 请求服务器。比较常用的方法有:

  • ajax
  • load
  • get
  • post
  • serialize
  • serializeArray

ajax 方法

这是最常用的方法,所有的 ajax 请求都可以用它来实现。它的方法中有个参数,是一个 JSON 对象,用来对ajax的请求进行配置。

$.ajax({
    url:"请求地址",
    type:"请求类型",
    async:布尔值|true:表示异步提交(默认)|false:表示同步提交,
    data:{传递给服务器的参数}|"键=值&键=值(这种形式封装)",
    success:function(data){
        // 服务器返回消息时调用,data是服务器返回的数据
    }
});

get 方法

只支持 get 请求的 ajax 方法,对上面方法的简化:

$.get("url",{传递给服务器的参数},function(data){
    // 服务器返回的消息
});

post 方法

只支持 post 请求的 ajax 方法,对上面方法的简化:

$.post("url",{传递给服务器的参数},function(data){
    // 服务器返回的消息
});

load 方法

这个方法的作用是向指定路径发送请求,并把返回的内容插入到指定的标签中:

$("#root").load("url",{传递给服务器的参数},function(){
    // 插入完成后执行
});

这个方法可以用来加载其他子页面。

本文链接:http://www.yanhongzhi.com/post/ajax.html

-- EOF --

Comments