Ajax你真的了解吗?看看这篇文章吧

来源:程序思维浏览:990次
Ajax你真的了解吗

什么是AJAX?

AJAX(Asynchronous Javascript And XML)翻译成中文就是“异步Javascript和XML”。即使用Javascript语言与服务器进行异步交互,传输的数据为XML(当然,传输的数据不只是XML)。

AJAX还有一个最大的特点就是,当服务器响应时,不用刷新整个浏览器页面,而是可以局部刷新。这一特点给用户的感受是在不知不觉中完成请求和响应过程。

与服务器异步交互;

浏览器页面局部刷新;

同步交互与异步交互

同步交互:客户端发出一个请求后,需要等待服务器响应结束后,才能发出第二个请求;
异步交互:客户端发出一个请求后,无需等待服务器响应结束,就可以发出第二个请求。

同步交互与异步交互


AJAX常见应用情景

当我们在百度中输入一个“传”字后,会马上出现一个下拉列表!列表中显示的是包含“传”字的10个关键字。

其实这里就使用了AJAX技术!当文件框发生了输入变化时,浏览器会使用AJAX技术向服务器发送一个请求,查询包含“传”字的前10个关键字,然后服务器会把查询到的结果响应给浏览器,最后浏览器把这10个关键字显示在下拉列表中。

整个过程中页面没有刷新,只是刷新页面中的局部位置而已!

当请求发出后,浏览器还可以进行其他操作,无需等待服务器的响应!

AJAX常见应用情景

当输入用户名后,把光标移动到其他表单项上时,浏览器会使用AJAX技术向服务器发出请求,服务器会查询名为zhangSan的用户是否存在,最终服务器返回true表示名为zhangSan的用户已经存在了,浏览器在得到结果后显示“用户名已被注册!”。
  1. 整个过程中页面没有刷新,只是局部刷新了;
  2. 在请求发出后,浏览器不用等待服务器响应结果就可以进行其他操作;
AJAX的优缺点

优点:
  1. AJAX使用Javascript技术向服务器发送异步请求;
  2. AJAX无须刷新整个页面;
  3. 因为服务器响应内容不再是整个页面,而是页面中的局部,所以AJAX性能高;

缺点:
  1. AJAX并不适合所有场景,很多时候还是要使用同步交互;
  2. AJAX虽然提高了用户体验,但无形中向服务器发送的请求次数增多了,导致服务器压力增大;
  3. 因为AJAX是在浏览器中使用Javascript技术完成的,所以还需要处理浏览器兼容性问题;
AJAX技术

AJAX第一例(发送GET请求)

准备工作

因为AJAX也需要请求服务器,异步请求也是请求服务器,所以我们需要先写好服务器端代码,即编写一个Servlet!

这里,Servlet很简单,只需要输出“Hello AJAX!”。

public class AServlet extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)

           throws ServletException, IOException {

       System.out.println("Hello AJAX!");

       response.getWriter().print("Hello AJAX!");

    }

}

AJAX核心(XMLHttpRequest)

其实AJAX就是在Javascript中多添加了一个对象:XMLHttpRequest对象。所有的异步交互都是使用XMLHttpRequest对象完成的。也就是说,我们只需要学习一个Javascript的新对象即可。

注意,各个浏览器对XMLHttpRequest的支持也是不同的!大多数浏览器都支持DOM2规范,都可以使用:var xmlHttp = new XMLHttpRequest()来创建对象

为了处理浏览器兼容问题,给出下面方法来创建XMLHttpRequest对象:

    function createXMLHttpRequest() {

       var xmlHttp;

       // 适用于大多数浏览器,以及IE7和IE更高版本

       try{

           xmlHttp = new XMLHttpRequest();

       } catch (e) {

           // 适用于IE6

           try {

              xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");

           } catch (e) {

              // 适用于IE5.5,以及IE更早版本

              try{

                  xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");

              } catch (e){}

           }

       }         

       return xmlHttp;

    }

打开与服务器的连接(open方法)

当得到XMLHttpRequest对象后,就可以调用该对象的open()方法打开与服务器的连接了。open()方法的参数如下:

open(method, url, async):

method:请求方式,通常为GET或POST;
url:请求的服务器地址,例如:/ajaxdemo1/AServlet,若为GET请求,还可以在URL后追加参数;
async:这个参数可以不给,默认值为true,表示异步请求;
       var xmlHttp = createXMLHttpRequest();

       xmlHttp.open("GET", "/ajaxdemo1/AServlet", true);

发送请求

当使用open打开连接后,就可以调用XMLHttpRequest对象的send()方法发送请求了。send()方法的参数为POST请求参数,即对应HTTP协议的请求体内容,若是GET请求,需要在URL后连接参数。

注意:若没有参数,需要给出null为参数!若不给出null为参数,可能会导致FireFox浏览器不能正常发送请求!

       xmlHttp.send(null);

接收服务器响应

当请求发送出去后,服务器端Servlet就开始执行了,但服务器端的响应还没有接收到。接下来我们来接收服务器的响应。

XMLHttpRequest对象有一个onreadystatechange事件,它会在XMLHttpRequest对象的状态发生变化时被调用。下面介绍一下XMLHttpRequest对象的5种状态:

0:初始化未完成状态,只是创建了XMLHttpRequest对象,还未调用open()方法;
1:请求已开始,open()方法已调用,但还没调用send()方法;
2:请求发送完成状态,send()方法已调用;
3:开始读取服务器响应;
4:读取服务器响应结束。

onreadystatechange事件会在状态为1、2、3、4时引发。

  下面代码会被执行四次!对应XMLHttpRequest的四种状态!

       xmlHttp.onreadystatechange = function() {

           alert('hello');

       };

但通常我们只关心最后一种状态,即读取服务器响应结束时,客户端才会做出改变。我们可以通过XMLHttpRequest对象的readyState属性来得到XMLHttpRequest对象的状态。

       xmlHttp.onreadystatechange = function() {

           if(xmlHttp.readyState == 4) {

              alert('hello');  

           }

       };

其实我们还要关心服务器响应的状态码是否为200,其服务器响应为404,或500,那么就表示请求失败了。我们可以通过XMLHttpRequest对象的status属性得到服务器的状态码。

最后,我们还需要获取到服务器响应的内容,可以通过XMLHttpRequest对象的responseText得到服务器响应内容。

responsXML是xml格式的文本,是document对象

       xmlHttp.onreadystatechange = function() {

           if(xmlHttp.readyState == 4 && xmlHttp.status == 200) {

              alert(xmlHttp.responseText);   

           }

       };

AJAX第一例小结

创建XMLHttpRequest对象;
调用open()方法打开与服务器的连接;
调用send()方法发送请求;
为XMLHttpRequest对象指定onreadystatechange事件函数,这个函数会在XMLHttpRequest的1、2、3、4,四种状态时被调用;
XMLHttpRequest对象的5种状态:

0:初始化未完成状态,只是创建了XMLHttpRequest对象,还未调用open()方法;
1:请求已开始,open()方法已调用,但还没调用send()方法;
2:请求发送完成状态,send()方法已调用;
3:开始读取服务器响应;
4:读取服务器响应结束。

通常我们只关心4状态。

XMLHttpRequest对象的status属性表示服务器状态码,它只有在readyState为4时才能获取到。

XMLHttpRequest对象的responseText属性表示服务器响应内容,它只有在readyState为4时才能获取到!

  <script type="text/javascript">

    var xmlHttp = new XMLHttpRequest();

    xmlHttp.open("GET", "/AJAX/AServlet");

    xmlHttp.send(null);

    xmlHttp.onreadystatechange = function(){

        if(xmlHttp.readyState == 4 && xmlHttp.status == 200){

            var h1 = document.getElementById("h1");

            h1.innerHTML = xmlHttp.responseText;

        }

    }

  </script>
  <body>
  <h1 id="h1"></h1>

  </body>
public class AServlet extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        response.setContentType("text/html;charset=utf-8");

        response.getWriter().print("hehe");

    }

}

AJAX第二例(发送POST请求)

发送POST请求注意事项

POST请求必须设置ContentType请求头的值为application/x-www.form-encoded。表单的enctype默认值就是为application/x-www.form-encoded!因为默认值就是这个,所以大家可能会忽略这个值!当设置了<form>的enctype=” application/x-www.form-encoded”时,等同与设置了Cotnent-Type请求头。

但在使用AJAX发送请求时,就没有默认值了,这需要我们自己来设置请求头:

xmlHttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");

当没有设置Content-Type请求头为application/x-www-form-urlencoded时,Web容器会忽略请求体的内容。所以,在使用AJAX发送POST请求时,需要设置这一请求头,然后使用send()方法来设置请求体内容。

xmlHttp.send("b=B");

这时Servlet就可以获取到这个参数!!!

AServlet

    public void doPost(HttpServletRequest request, HttpServletResponse response)

           throws ServletException, IOException {

       System.out.println(request.getParameter("b"));

       System.out.println("Hello AJAX!");

       response.getWriter().print("Hello AJAX!");

    }

ajax2.jsp

<script type="text/javascript">

function createXMLHttpRequest() {

    try {

       return new XMLHttpRequest();//大多数浏览器

    } catch (e) {

       try {

           return new ActiveXObject("Msxml2.XMLHTTP");

       } catch (e) {

           return new ActiveXObject("Microsoft.XMLHTTP");

       }

    }

}

 

function send() {

    var xmlHttp = createXMLHttpRequest();

    xmlHttp.onreadystatechange = function() {

       if(xmlHttp.readyState == 4 && xmlHttp.status == 200) {

           var div = document.getElementById("div1");

           div.innerHTML = xmlHttp.responseText;

       }

    };

    xmlHttp.open("POST", "/ajaxdemo1/AServlet?", true);

    xmlHttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");

    xmlHttp.send("b=B");

}

</script>

<h1>AJAX2</h1>

<button onclick="send()">测试</button>

<div id="div1"></div>

AJAX第三例(用户名是否已被注册)

功能介绍

在注册表单中,当用户填写了用户名后,把光标移开后,会自动向服务器发送异步请求。服务器返回true或false,返回true表示这个用户名已经被注册过,返回false表示没有注册过。

客户端得到服务器返回的结果后,确定是否在用户名文本框后显示“用户名已被注册”的错误信息!

案例分析

regist.jsp页面中给出注册表单;
在username表单字段中添加onblur事件,调用send()方法;
send()方法获取username表单字段的内容,向服务器发送异步请求,参数为username;
RegistServlet:获取username参数,判断是否为“itcast”,如果是响应true,否则响应false;

代码

regist.jsp

    <script type="text/javascript">

        function ajax(){

            var userText = document.getElementById("username");

            var username = userText.value;

            var xmlHttp = new XMLHttpRequest();

            xmlHttp.open("GET", "<c:url value="/ValidateUserNameServlet"/>?username="+username );

            xmlHttp.send(null);

            xmlHttp.onreadystatechange = function(){

                if(xmlHttp.readyState == 4 && xmlHttp.status == 200){

                   var span = document.getElementById("span1");

                   if(xmlHttp.responseText == "true"){

                       span.innerHTML = "用户名可用";

                   }else{

                       span.innerHTML = "用户名已被注册";

                   }

                }

            }

        }

    </script> 

  <form action="" method="post">

    用户名:<input type="text"id = "username" name="username" onblur="ajax()"><span id="span1"></span><br>

    <input type="submit" >

  </form>

RegistServlet.java

    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        String username = request.getParameter("username");

        System.out.println(username);

        if(username.equals("admin")){

            response.getWriter().print(false);

        }else{

            response.getWriter().print(true);

        }

    }

Ajax经典总结:

asynchronous javascript and xml:异步的javascript和xml。

ajax是一种用来改善用户体验的技术,其本质是利用浏览器内置的一种特殊的对象(XMLHttpRequest)异步(即发送请求时,浏览器不会销毁当前页面,用户可以继续在当前页面做其它的操作)的向服务器发送请求,并且利用服务器返回的数据(不再是一个完整的页面,只是部分的数据,一般使用文本或者xml返回)来部分更新当前页面。使用ajax技术之后,页面无刷新,并且不打断用户

的操作。

ajax技术的优点:

(1).页面无刷新

(2).不打断用户的操作,用户的体验好。

(3).按需获取数据,浏览器与服务器之间数据的传输量减少。

(4).是一个标准技术,不需要下载任何的插件。

(5).可以利用客户端(浏览器)的计算能力。

2、ajax对象

(1)如何获得ajax对象?

XMLHttpRequest并没有标准化,要区分浏览器:

function getXhr(){

var xhr;

if(window.XMLHttpRequest){

//非ie浏览器

xhr = new XMLHttpRequest();

}else{

//ie

xhr = new ActiveXObject('Microsoft.XMLHttp');

}

}

ajax经典总结

(2)ajax对象的属性

a, onreadystatechange : 绑订一个事件处理函数(注册监听器),当

                                ajax对象的readyState值发生了改变(比如,

                                从0-->1),就会产生readystatechange事

                                件。

b, responseText: 获得服务器返回的文本

c, responseXML:获得服务器返回的xml数据

d, status:获得状态码

e, readyState:ajax对象在与服务器进行通讯时,通过readyState属

                       性值可以获取该对象的通讯的状态,其属性有5个

                      (0,1,2,3,4),当属性值为4时,表示ajax对象已经获得了

                      服务器返回的所有的数据。

            0:(未初始化)对象已建立(获得),但是尚未初始化(尚未调用open

                方法)

            1:(初始化)对象已建立,调用了open方法但尚未调用send方法。

            2:(发送数据)send方法一调用。

            3:(数据传送中)已接收部分数据。

            4:(响应结束)接收了所有的数据。

             ajax经典总结   

(3)ajax编程的基本步骤

step1, 先获得ajax对象

var xhr = getXhr();

step2, 发送请求

xhr.open(请求方式,请求地址,异步还是同步);

请求方式: get/post

请求地址:如果是get请求,请求参数要添加到请求地址的后面。

true表示异步请求 :ajax对象发请求的同时,用户可以对当前页

                                面做其它的操作。

false表示同步请求:ajax对象发请求的同时,浏览器会锁订当前页

                              面,用户需要等待处理完成之后,浏览器才会

                              解除锁定,才能做下一步操作。

方式一:get请求

xhr.open('get',

'check_username.do?username=zs',true);

xhr.onreadystatechange=f1;

xhr.send(null);

方式二:post请求

xhr.open('post');

step3,编写服务器端的代码,服务器端一般不需要返回完整的页面,

                只需要返回部分的数据,比如一个简单的字符串。

step4, 编写监听器

function f1(){

if(xhr.readyState == 4){

//获得服务器返回的数据

var txt = xhr.responseText;

//dom操作

}

}

eg:

function check_username() {

//step1,获得ajax对象

var xhr = getXhr();

 

         document.write(xhr.readyState+"<br/>");//0

 

//step2, 发请求

xhr.open('get', 'check_username.do?username=' + $F('username'), true);//建立连接

 

document.write(xhr.readyState+"<br/>");//1

 

xhr.onreadystatechange = function() {//绑定事件处理函数(注册监

                                             听器)

//只有ajax对象的readyState值为4时,才能获得服务器返回的完整。

            数据                                       

document.write(xhr.readyState+"<br/>");//依次输出2、3、4

 

if (xhr.readyState == 4) {

//获得服务器返回的文本数据

var txt = xhr.responseText;

//更新页面

$('username_msg').innerHTML = txt;

}

};

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

}

 

XMLHttpRequest对象xhr通过onreadystatechange属性绑定了事件处理函数,在整个会话内,onreadystatechange属性会发生多次变化,依次从0-1-2-3-4,每一次属性值的变化都会触发绑定事件函数的执行。

eg:同步、异步问题:

// 验证验证码是否正确

function check_code() {

var flag =false;

// step1,获得ajax对象

var xhr = getXhr();

// step2, 发请求

var uri = 'check_code.do?checkcode=' + $F('checkcode');

xhr.open('get', encodeURI(uri), false);// 建立连接

xhr.onreadystatechange = function() {// 绑定事件处理函数(注册监听器)

// 只有ajax对象的readyState值为4时,才能获得服务器返回的数据。

if (xhr.readyState == 4) {

if (xhr.status  == 200) {

// 获得服务器返回的文本数据

var txt = xhr.responseText;

// 更新页面

if (txt == "error") {

$('checkcode_msg').innerHTML = "验证码错误!";

flag = false;

} else {

$('checkcode_msg').innerHTML = "验证码正确!";

flag = true;

}

} else {

$('checkcode_msg').innerHTML = '系统繁忙,验证出错';

flag = false;

}

}

};

$('checkcode_msg').innerHTML = "正在验证......";// 当服务器响应比较慢时可以看到此提示

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

//当ajax对象向服务器发送同步请求时,

//浏览器不会向下执行,会等待服务器的响应。

//如果是异步,send后,并不会先执行绑定事件,而是先向下执行

//在监听事件中返回值有问题,所以没在其中返回

return flag;

}

当为异步方式时,返回的flag始终是false,flag在监听事件中被有被改变(监听事件在return之前没有执行),所以要设置为同步方式,这样在return falg之前,监听事件就会处理完毕,flag的值就会发生相应的改变。

3、ajax编程中的编码问题

(1)发送get请求:

ie浏览器内置的ajax对象,对中文参数使用gbk编码,而其它浏览器

       (firefox,chrome)使用utf8编码。

服务器端默认使用iso-8859-1去解码。

解决方案:

step1,让服务器对get请求中的参数使用指定的编码格式进行解码。

比如,对于tomcat,可以修改 conf/server.xml,只对get方式有效

<Connector port="8080" protocol="HTTP/1.1" 

          connectionTimeout="20000" 

          URIEncoding="utf-8"(要加入的代码)

          redirectPort="8443" />

      <!-- A "Connector" using the shared thread pool-->

     ajax经典总结

step2,对请求地址,使用encodeURI函数进行统一的编码(utf-8)

            var uri = 'check_username.do?username='+ $F('username');

xhr.open('get',encodeURI(uri),true);

(2)发送post

如果发送方式为post,那么所有浏览器内置的ajax对象都会对请求参数

       使用utf-8进行编码,那么只要在服务器端设置:

         request.setCharacterEncoding("utf-8");

4、发送post请求

xhr.open('post','check_username.do',true);

xhr.setRequestHeader('content-type','application/x-www-form-urlencoded');

xhr.onreadystatechange=f1;

xhr.send('username=' + $F('username'));

注意:

因为按照http协议的要求,如果发送的post请求,那么请求数据包里面,

       应该有一个消息头 content-type。但是,ajax对象默认没有,所以,需

       要调用setRequestHeader方法。

5、json (javascript object notation)

(1)json是什么?

是一种轻量级的数据交换标准。

a,什么是数据交换?

简单地讲,就是将要交换的数据先转换成一个与平台无关的数据格式(比

       如xml或者json字符串)发送给接受方,接受方再进行相应的转换。

b,轻量级

相对于xml,json解析的速度更快,数据量更小。

(2)json语法格式

1)如何表示一个对象

{属性名:属性值,属性名:属性值...}

要注意:

 a,属性值的类型可以是string,number,null,boolean, object。

 b,属性名必须使用引号括起来

 c,属性值如果是string,也必须使用引号括起来

2)如何表示一个对象组成的数组

[{},{},{}...]

(3)如何使用json做数据交换

1)java对象(java对象组成的数组或者集合)转换成对应的json字符串

可以从www.json.org去下载对应语言的工具。

使用的json-lib中提供的两个类:

JSONObject, JSONArray

2)json字符串转换成javascript对象

可以使用prototype提供的evalJSON函数。

prototype.js提供了很多有用的函数:

a, $(id):  document.getElementById(id);

b, $F(id): document.getElementById(id).value;

c,  $(id1,id2,...): 分别查找id为id1,id2...的节点,然后返回一

                               个数组。

d, strip(): 除掉字符串两端的空格。

e, evalJSON():将json字符串转换成对应的javascript对象或者

                            数 组。

 ajax经典总结

练习:热卖商品动态显示

step1,建表

create table t_sale(

id int primary key auto_increment,

name varchar(50),

price double,

qty int

);

insert into t_sale(name,price,qty) values('bmwx6',20,30);

insert into t_sale(name,price,qty) values('bmwx5',20,20);

insert into t_sale(name,price,qty) values('bmwx3',20,60);

insert into t_sale(name,price,qty) values('bmwx1',20,40);

查询销量前三的sql:

  select * from t_sale order by qty desc limit 3;

step2, 实体类  Sale

step3, SaleDAO

List<Sale> find...

step4,  ActionServlet

输出一个json字符串

step5, 测试ActionServlet

step6,  sale.jsp

 

6、ajax应用中的缓存问题:

当使用IE浏览器时,如果使用get方式发请求,浏览器会先缓存之前

访问的数据,如果访问的地址不变,不会向服务器发请求。

解决方式1:使用post方式发请求。

解决方式2: 在请求地址后面添加一个随机数。

7、发送同步请求

xhr.open('post','check_username.do',false);

  function check_username(){

var xhr = getXhr();xhr.open('post','show.do',true);

xhr.setRequestHeader('content-type','application/x-www-form-urlencoded');

xhr.onreadystatechange=function(){

if(xhr.readState == 4){

 var txt = xhr.responseText;alert(txt);

        $('username_msg').innerHTML=txt;

      }

};

xhr.send('username=' + $F('username'));

//当ajax对象向服务器发送同步请求时,浏览器不会向下执行,会等待服务器的响应。在完整的收到服务器返回的数据之前,浏览器便处于锁定状态,用户不可进行操作。

}
精品好课
Vue2+Vue3+ES6+TS+Uni-app开发微信小程序从入门到实战视频教程
2021年最新Vue2+Vue3+ES6+TypeScript和uni-app开发微信小程序从入门到实战视频教程,本课程教你如何快速学会VUE和uni-app并应用到实战,教你如何解决内存泄漏,常用UI库的使用,自己...
最新完整React视频教程从入门到精通纯干货纯实战
React是目前最火的前端框架,就业薪资很高,本课程教您如何快速学会React并应用到实战,教你如何解决内存泄漏,常用UI库的使用,自己封装组件,正式上线白屏问题,性能优化等。对正在工作当中或打算学习React高薪就...
jQuery视频教程从入门到精通
jquery视频教程从入门到精通,课程主要包含:jquery选择器、jquery事件、jquery文档操作、动画、Ajax、jquery插件的制作、jquery下拉无限加载插件的制作等等......
HTML5基础入门视频教程易学必会
HTML5基础入门视频教程,教学思路清晰,简单易学必会。适合人群:创业者,只要会打字,对互联网编程感兴趣都可以学。课程概述:该课程主要讲解HTML(学习HTML5的必备基础语言)、CSS3、Javascript(学习...
React实战视频教程仿京东移动端电商
React是前端最火的框架之一,就业薪资很高,本课程教您如何快速学会React并应用到实战,对正在工作当中或打算学习React高薪就业的你来说,那么这门课程便是你手中的葵花宝典。
HTML5视频播放器video开发教程
适用人群1、有html基础2、有css基础3、有javascript基础课程概述手把手教你如何开发属于自己的HTML5视频播放器,利用mp4转成m3u8格式的视频,并在移动端和PC端进行播放支持m3u8直播格式,兼容...
最新完整React+VUE视频教程从入门到精,企业级实战项目
React和VUE是目前最火的前端框架,就业薪资很高,本课程教您如何快速学会React和VUE并应用到实战,教你如何解决内存泄漏,常用库的使用,自己封装组件,正式上线白屏问题,性能优化等。对正在工作当中或打算学习Re...
VUE2+VUE3视频教程从入门到精通(全网最全的Vue课程)
VUE是目前最火的前端框架之一,就业薪资很高,本课程教您如何快速学会VUE+ES6并应用到实战,教你如何解决内存泄漏,常用UI库的使用,自己封装组件,正式上线白屏问题,性能优化等。对正在工作当中或打算学习VUE高薪就...
收藏
扫一扫关注我们