Ajax

Posted samuraihuang

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Ajax相关的知识,希望对你有一定的参考价值。

ajax简介

Ajax的全称是:Asynchronous javascript And XML,指的是异步 JavaScript 及 XML(其实主要用的就是javascript技术),它不是一种新的编程语言,而是一种用于创建更好更快以及交互性更强的 Web 应用程序的技术。Ajax的特点是异步,比如可以使用Ajax更新局部网页、使用Ajax在不刷新页面的情况下查询数据、验证用户注册的用户名是否唯一等。

Ajax交互模型:

 

技术图片

 

同步web交互方式

技术图片

异步web交互方式

技术图片

XMLHttpRequest对象

JavaScript中XMLHttpRequest对象是整个Ajax技术的核心,它提供了异步发送请求的能力。
对象的创建方式
对于不同的浏览器,对象的创建方式是不同的。

var xmlhttp;
    if (window.XMLHttpRequest) {// code for IE7+, Firefox, Chrome, Opera, Safari
        xmlhttp = new XMLHttpRequest();
    } else {// code for IE6, IE5
        xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
    }
return xmlhttp;

常用方法

  • open(method,URL,async)
    建立与服务器的连接
    method参数指定请求的HTTP方法,典型的值是GET或POST
    URL参数指请求的地址
    async参数指定是否使用异步请求,其值为true或false,默认是true
  • send(content)
    发送请求
    content指定请求的参数
  • setRequestHeader(header,value)
    设置请求的头信息

常用属性

  • onreadystatechange
    指定回调函数
  • readyState
    XMLHttpRequest的状态信息

 

就绪状态码说明
0 XMLHttpRequest对象没有完成初始化即:刚刚创建。
1 XMLHttpRequest对象开始发送请求调用了open方法,但还没有调用send方法。请求还没有发出
2 XMLHttpRequest对象的请求发送完-成send方法已经调用,数据已经提交到服务器,但没有任何响应
3 XMLHttpRequest对象开始读取响应,还没有结束收到了所有的响应消息头,但正文还没有完全收到
4 XMLHttpRequest对象读取响应结束一切都收到了

 

 

使用Ajax校验用户名

通常情况下在一个系统中的用户的登录名是唯一的,为了保证用户名的唯一性,需要在用户注册时添加校验,即根据用户输入的用户名去数据库中查找,这里使用ajax校验用户名可以很好的提升用户体验,用户输入完用户名失去鼠标焦点后通过ajax去数据库中查找是否唯一,然后根据结果给用户相应的提示信息,这样对于用户来说非常方便。

什么是回调函数
回调函数就是你编写好了一个函数,让软件系统来调用这个函数,该函数就是回调函数。说的简单点其实就是让系统调用你的函数就是回调,那你调用系统的函数是直调。
举例来说,你跟马云谈生意,聊天结束后,你跟马云说以后有什么需要帮助的可以联系我的秘书小张。这个秘书小张就可以看做是回调函数,当马云联系你的秘书小张时,叫做调用回调函数。

代码示例:

创建jsp添加一个表单:

1 <body>
2         用户名:<input type="text" name="name" /><span id="msg"></span><br/>
3 </body>

 

在jsp中添加onblur事件绑定,然后使用ajax完成异步请求

 1 <script type="text/javascript">
 2     window.onload=function(){
 3         var nameElement = document.getElementById("name");
 4         //绑定onblur事件
 5         nameElement.onblur = function(){
 6             //this等价于nameElement
 7             var name = this.value;
 8             //创建XMLHttpRequest对象
 9             var xhr;
10             if (window.XMLHttpRequest) {// code for IE7+, Firefox, Chrome, Opera, Safari
11                 xhr = new XMLHttpRequest();
12             } else {// code for IE6, IE5
13                 xhr = new ActiveXObject("Microsoft.XMLHTTP");
14             }
15             //注册回调函数
16             xhr.onreadystatechange = function(){
17                 if(xhr.readyState==4){//请求一切正常
18                     if(xhr.status==200){//服务器响应一切正常
19                         var msg = document.getElementById("msg");
20                         if(xhr.responseText=="true"){
21                             msg.innerhtml =  "<font color=‘red‘>用户名已存在</font>";
22                            
23                         }else{
24                             msg.innerHTML = "可以使用";
25                         }
26                     }
27             }
28         }
29 
30         //创建连接
31         xhr.open("get","${pageContext.request.contextPath }/regist?name="+name);
32         //发送请求
33         xhr.send(null);
34         }
35 
36     }
37 </script>

 

创建用来处理请求的servlet,这里省略JDBC数据库相关的操作,直接将用户名写死在程序中:

 1 package com.monkey1024.servlet;
 2 
 3 import java.io.IOException;
 4 import java.io.PrintWriter;
 5 
 6 import javax.servlet.ServletException;
 7 import javax.servlet.http.HttpServlet;
 8 import javax.servlet.http.HttpServletRequest;
 9 import javax.servlet.http.HttpServletResponse;
10 
11 /**
12  * 注册
13  */
14 public class RegistServlet extends HttpServlet {
15     private static final long serialVersionUID = 1L;
16 
17     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
18         PrintWriter out = response.getWriter();
19         String name = request.getParameter("name");
20         if("monkey1024".equals(name)){
21             out.print(true);
22         }else{
23             out.print(false);
24         }
25     }
26 
27     protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
28         doGet(request, response);
29     }
30 
31 }

 

百度下拉提示框

在使用百度搜索时,在输入框中输入部分文字后,下面会将与该文字相关的词组展示出来,该功能就可以使用ajax来实现。
注册输入框的onkeyup事件,该事件触发时,将输入框中填写的内容使用ajax发送到servlet中,在servlet中根据用户的输入去数据库中查询,之后将查询出的数据再发送给jsp中,最后将该数据展示在页面即可。

代码示例:

定义jsp:

 1 <!-- 用户输入框 -->
 2 <div id="divsearch">
 3         <input type="text" name="name" id="name" />
 4         <input type="submit" value="搜索">
 5 
 6 </div>
 7 <!-- 下拉提示框 -->
 8 <div id="tips"
 9     style="display: none; border: 1px solid red;  width: 128px; top: 135px;">
10 
11 </div>

 

在jsp中编写javascript代码:

 1 <script type="text/javascript">
 2     window.onload = function(){
 3 
 4         var searchElement = document.getElementById("name");
 5         var div = document.getElementById("tips");
 6 
 7         //给文件框注册按键弹起事件
 8         searchElement.onkeyup = function(){
 9             //获取文本框的值
10             var name = this.value;
11             //如果文本框没有数据时,将div隐藏。
12             if(name==""){
13                 div.style.display="none";
14                 return;
15             } 
16 
17             //获得XMLHttpRequest对象
18             var xhr = getXMLHttpRequest();
19 
20             //回调函数
21             xhr.onreadystatechange = function(){
22                 if(xhr.readyState==4){//请求一 切正常
23                     if(xhr.status==200){//服务器响应一切正常
24                         var str = xhr.responseText;//得到服务器返回的数据
25                         if(str == ""){
26                             return;
27                         }
28                         var result = str.split(","); // 把返回的数据截成数组
29                         var childDivs = "";
30                         //循环把数据放入div中
31                         for(var i=0;i<result.length;i++){
32                             //把数组中的每个元素放到div中
33                             childDivs+="<div onclick=‘writeText(this)‘ onmouseover=‘changeBackground_over(this)‘ onmouseout=‘changeBackground_out(this)‘>"+result[i]+"</div>";
34                         }
35 
36                         div.innerHTML= childDivs;//把多个childDivs(div)放入列表div中
37                         div.style.display="block";//把列表显示
38                     }
39                 }
40             }
41 
42             xhr.open("get","${pageContext.request.contextPath}/search?name="+name+"&time="+new Date().getTime());
43 
44             xhr.send(null);
45         }
46     }
47 
48     function getXMLHttpRequest(){
49          var xhr;
50          if (window.XMLHttpRequest) {//IE7+, Firefox, Chrome, Opera, Safari
51              xhr = new XMLHttpRequest();
52          } else {//IE6, IE5
53              xhr = new ActiveXObject("Microsoft.XMLHTTP");
54          }
55          return xhr;
56     }
57 
58     //鼠标悬浮时,改变背景色
59     function changeBackground_over(div){
60         div.style.backgroundColor = "orange";
61     }
62     //鼠标离开时,恢复背景色
63     function changeBackground_out(div){
64         div.style.backgroundColor = "";
65     }
66 
67     //将文本填充到搜索框
68     function writeText(div){
69         //得到搜索框
70         var searchElement = document.getElementById("name");
71         searchElement.value = div.innerHTML;//把div中的文本添加到搜索框中
72         div.parentNode.style.display="none";//把context1的div隐藏
73     }
74 </script>

 

编写servlet用来接收ajax请求并查询数据,这里简化下不去数据库中查询,而是自己构建一个List,将该List作为查询的结果返回给jsp:

 1 package com.monkey1024.servlet;
 2 
 3 import java.io.IOException;
 4 import java.util.ArrayList;
 5 import java.util.List;
 6 
 7 import javax.servlet.ServletException;
 8 import javax.servlet.http.HttpServlet;
 9 import javax.servlet.http.HttpServletRequest;
10 import javax.servlet.http.HttpServletResponse;
11 
12 /**
13  * 查询
14  */
15 public class SearchServlet extends HttpServlet {
16     private static final long serialVersionUID = 1L;
17 
18     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
19 
20         String name = request.getParameter("name");
21 
22         //根据用户输入的数据去查询数据库,这里省略数据库查询操作,手动编写一个List结果集
23         List<String> result = new ArrayList<>();
24         result.add("m1");
25         result.add("m2");
26         result.add("m3");
27         result.add("m4");
28         result.add("m5");
29 
30         //把集合中的数据转换为字符串返回到网页
31         String str = "";
32         //如果用户输入的内容是以m开头的话,则将数据返回
33         if(name.startsWith("m")){
34             for (int i = 0; i < result.size(); i++) {
35                 if(i>0){
36                     str+=",";
37                 }
38                 str+=result.get(i);
39             }
40         }
41 
42         System.out.println(str);
43         //把数据响应到客户端
44         response.getWriter().write(str);
45     }
46 
47     protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
48         doGet(request, response);
49     }
50 
51 }

 

 

json简介

json的全称是JavaScript Object Notation,是一种数据交换格式,独立于编程语言,可以用来存储数据,优点是非常利于人类阅读和编写,同时也利于机器的解析和生成,同时还可以提升网络传输效率。
json的数据格式是以名-值对的方式存储的,可以将其看做是一个字符串,下面就是一个json格式的数据:

{name:"monkey1024",age:18,hobby:"java"}

在json中规定的字符编码时utf-8,无需担心乱码问题。几乎所以的编程语言都有解析json数据的第三方库,因此json的应用非常多。在servlet中可以将要返回给jsp的数据封装为json格式,在jsp中可以使用javascript来解析,javascript已经内置了json的解析。

在javascript中创建json对象:

 1 <script type="text/javascript">
 2 
 3     //创建一个json对象
 4     var student = {name:"jack",age:18};
 5     alert(student.name);
 6 
 7     //创建一个数组,数组中存放json对象
 8     var animal = [{name:"monkey",count:10},{name:"tiger",count:5}];
 9     alert(animal[0].name);
10 </script>

 

通过上面示例可以看出在javascript中使用json非常方便。

在java中有非常多的第三方库可以解析json格式的数据,常用的有:

fastjson:国人开发的,是目前java语言中最快的json库
gson:google开发
jackson:Tatu Saloranta开发

下面以fastjson为例看下,fastjson相关jar包下载地址:http://pan.baidu.com/s/1jIagJII
fastjson中常用的方法:

  • JSON.toJSONString
    将JavaBean转成json格式的字符串
  • JSON.parseObject
    将json格式的字符串转换为JavaBean

代码示例:

创建一个City类,表示城市:

 1 package com.monkey1024.bean;
 2 
 3 /**
 4  * 城市
 5  *
 6  */
 7 public class City {
 8 
 9     private int id;
10 
11     private String name;
12 
13     public int getId() {
14         return id;
15     }
16 
17     public void setId(int id) {
18         this.id = id;
19     }
20 
21     public String getName() {
22         return name;
23     }
24 
25     public void setName(String name) {
26         this.name = name;
27     }
28 
29 }

 

创建一个Province类表示省份:

 1 package com.monkey1024.bean;
 2 
 3 import java.util.List;
 4 
 5 /**
 6  * 省份
 7  *
 8  */
 9 public class Province{
10 
11     private String name;
12 
13     private List<City> cities;
14 
15     public String getName() {
16         return name;
17     }
18 
19     public void setName(String name) {
20         this.name = name;
21     }
22 
23     public List<City> getCities() {
24         return cities;
25     }
26 
27     public void setCities(List<City> cities) {
28         this.cities = cities;
29     }
30 
31 }

 

fastjson测试类:

 1 package com.monkey1024.test;
 2 
 3 import java.util.ArrayList;
 4 import java.util.List;
 5 
 6 import com.alibaba.fastjson.JSON;
 7 import com.monkey1024.bean.City;
 8 import com.monkey1024.bean.Province;
 9 
10 public class JsonTest {
11 
12     public static void main(String[] args) {
13 
14         City c1 = new City();
15         c1.setId(1005);
16         c1.setName("石家庄");
17 
18         City c2 = new City();
19         c2.setId(1006);
20         c2.setName("唐山");
21 
22         City c3 = new City();
23         c3.setId(1007);
24         c3.setName("保定");
25 
26         List<City> cities = new ArrayList<>();
27         cities.add(c1);
28         cities.add(c2);
29         cities.add(c3);
30 
31         Province hebei = new Province();
32         hebei.setName("河北");
33         hebei.setCities(cities);
34         //将Province对象转换为json格式并返回字符串
35         String hebeiString = JSON.toJSONString(hebei);
36         System.out.println(hebeiString);
37 
38         //将json格式的字符串转换为Province对象
39         Province hebeiNew = JSON.parseObject(hebeiString, Province.class);
40         System.out.println(hebeiNew.getName());
41 
42     }
43 
44 }

 

使用json进行数据传输

将百度下拉提示框中的代码改成使用json格式进行数据传输。
将SearchServlet类中的doGet方法修改为下面内容:

// 根据用户输入的数据去查询数据库,这里省略数据库查询操作,手动编写一个List结果集
1 List<String> result = new ArrayList<>();
2 result.add("m1");
3 result.add("m2");
4 result.add("m3");
5 result.add("m4");
6 result.add("m5");

//将List转换为string类型
1 String str = JSONArray.toJSONString(result);

// 把数据响应到客户端
1 response.getWriter().write(str);

 

因为servlet中返回了一个JSON字符串,所以需要在javascript中将该字符串转换为JSON类型,因此将search.jsp中的

1 var result = str.split(",");

 

修改为:

1 var result = JSON.parse(str);

 

上面代码中将字符串转换为JSON对象。

由此可见使用json进行数据传输时可以减少开发者的操作并且提高系统的运行效率(之前需要遍历list并进行拼接)。

 

以上是关于Ajax的主要内容,如果未能解决你的问题,请参考以下文章

Javascript代码片段在drupal中不起作用

前端面试题之手写promise

Ajax 片段元标记 - Googlebot 未读取页面内容

执行AJAX返回HTML片段中的JavaScript脚本

javascript AJAX片段

Spring MVC 3.2 Thymeleaf Ajax 片段