Ajax介绍 Ajax主要作用:在不刷新网页的情况下,与后台数据进行交互,从而实现页面局部刷新的功能
Asynchronous JavaScript And Xml(异步的JavaScript和XML)
Ajax可以在不刷新页面的前提下,进行页面局部更新
Ajax不是新的技术,Ajax并不是W3C的标准
Ajax并不是一种标准,而是服务商提供的一种技术;大部分浏览器在浏览器内核中都提供了Ajax的核心实现;后来某位大牛对这些技术进行整合和命名,才有今天的Ajax
学习Ajax时,需要理解几点:
(1)以前遇到的请求都是和一个网页面联系在一起的,即前端发起一个请求就是和一个网页联系在一起,也可以理解为以前接触到的都是为了展示一个全新的页面而发起的一个请求,也可以理解为每发起一个新的请求,都会创建一个新的界面来展示一个新的界面来展示本次响应的内容;但Ajax不是这样的,Ajax的请求内容并不是为了展示一个新的界面,而是将本次请求的响应内容,局部刷新展示在已有界面上,本质是,已有页面发起一个没有和新的页面绑定的请求(这个请求和已有界面的局部刷新有关)
而这个功能的实现,浏览器中内嵌的ajax起到了重要作用
(2)一个可以接受请求,发出响应的servlet的任务仅仅是接受前台请求数据,处理后再返回给前台,具体响应后,前台怎么展示这些数据就和后台Servlet无关了
(3)目前可以这样理解:ajax是内嵌到浏览器中的一种技术,归浏览器解释;当浏览器解析到前端文件中的ajax部分的时候,浏览器会自动采用内置的ajax去解释
Ajax使用流程简介和准备工作 一.Ajax使用流程简介
创建XmlHttpRequest对象
发送Ajax请求(通过XmlHttpRequest对象发送请求)
处理服务器响应(在web页面中,通过JavaScript对响应进行后续的处理,将其显示在页面中)
二.准备工作 创建Web工程ajax,并创建ContentServlet和index.html:
index.html:
1 2 3 4 5 6 7 8 9 10 11 12 <!DOCTYPE html > <html lang ="en" > <head > <meta charset ="UTF-8" > <title > text ajax</title > </head > <body > <input id ="btnLoad" type ="button" value ="加载" > <div id ="divContent" > </div > </body > </html >
ContentServlet.java:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 import javax.servlet.*;import javax.servlet.http.*;import javax.servlet.annotation.*;import java.io.IOException;@WebServlet(name = "ContentServlet", value = "/ContentServlet") public class ContentServlet extends HttpServlet { @Override protected void doGet (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.getWriter().println("<br>I'm server Content</br>" ); } }
目前的需求是:当点击”加载”按钮的时候,向服务器发送请求,将回显动态写入到divContent中;即局部刷新和加载
三.利用Ajax实现Ajax请求 1.创建XmlHttpRequest对象
效果:
2.发送Ajax请求
xmlhttp.open()用于创建请求
xmlhttp.send()用于发送请求
1 2 3 4 5 6 <script > xmlhttp.open ("GET" ,"http://localhost:8080/ajax/content" ,"true" ); xmlhttp.send (); </script >
效果:
查看content:
查看response:
当多次点击”加载”按钮时:
3.处理服务器的响应
xmlhttp.onreadystatechange()事件用于监听AJAX的执行过程:这个方法用于捕捉Ajax的执行过程
xmlhttp.readyState属性说明XMLHttpRequest当前的状态:XmlhttpRequest对象中的一个重要属性,readState用于指示说明当前Ajax执行到哪一步了
readState值
说明
readState=0
请求未初始化
readState=1
服务器连接已建立
readState=2
请求已被接受
readState=3
请求正在处理
readState=4
响应文本已被接受
xmlhttp.status属性服务器响应状态码,200:成功,404:未找到……
(1)核心事件是onreadystatechange,当ajax在发送过程中,各个状态发生变化的时候,就会触发这个事件;(注:onreadystatechange是XmlHttpRequest对象的事件)
(2)readState用以判断Ajax执行到哪一步,最重要的是为4的时候;(注意:status是XmlHttpRequest对象的属性)
(3)status:服务器处理的状态,200代表处理成功(注意:status是XmlHttpRequest对象的属性)
readState=4和status=200,就代表响应已经被接受,而且服务是处理成功了。(服务器处理不成功时,其也还是会有响应的,只是这个响应是一个出错的响应,比如当status=404的时候,对于响应出错的时候,后续应该采取其他策略
(4)使用了XmlHttpRequest对象的responseText属性,获取服务器响应的文本;(注意:responseText是XmlHttpRequest对象的属性)获取服务器响应的文本后,对这个文本进行后续处理就可以了;(这个文本一般是JSON形式的,JSON作为一种功能强大,前后端都能解释得表示方法很给力)
Ajax处理响应得标准范例:
1 2 3 4 5 6 7 8 9 10 <script > xmlhttp.onreadstatechange =function ( ){ if (xmlhttp.readyState =4 &&xmlhttp.status =200 ) var responseText = xmlhttp.responseText ; …… } </script >
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 <!DOCTYPE html > <html lang ="en" > <head > <meta charset ="UTF-8" > <title > text ajax</title > </head > <body > <input id ="btnLoad" type ="button" value ="加载" > <div id ="divContent" > </div > <script > document .getElementById ("btnLoad" ).onclick = function ( ) { var xmlhttp; if (window .XMLHttpRequest ) { xmlhttp = new XMLHttpRequest (); } else { xmlhttp = new ActiveXObject ("Microsoft.XMLHTTP" ); } console .log (xmlhttp); xmlhttp.open ("GET" ,"/ajax/content" ,true ); xmlhttp.send (); xmlhttp.onreadystatechange =function ( ){ if (xmlhttp.readyState == 4 &&xmlhttp.status ==200 ){ var t =xmlhttp.responseText ; alert (t); document .getElementById ("divContent" ).innerHTML =t; } } } </script > </body > </html >
效果:
利用Ajax实现新闻列表 这个例子主要是展示在实际中,前后端交互的时候,传输的文本常常是JSON形式
News.java:定义构成函数等
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 public class News { private String title; private String date; private String source; private String content; public News () { } public News (String title, String date, String source, String content) { this .title = title; this .date = date; this .source = source; this .content = content; } public String getTitle () { return title; } public void setTitle (String title) { this .title = title; } public String getDate () { return date; } public void setDate (String date) { this .date = date; } public String getSource () { return source; } public void setSource (String source) { this .source = source; } public String getContent () { return content; } public void setContent (String content) { this .content = content; } }
NewListServlet类:
(1)后台处理后的数据向前台传的时候,需要转成JSON字符串;这需要引入fastjson的jar包
(2)这个Servlet并没有主动重定向或者转发至news.html中;而是在这里默默的等待,等待news,html的Ajax的XmlHttpServlet对象创建的Ajax请求,然后请求到这个Servlet中
(3)这个Servlet通过,response.getWriter().println(newsJsonStr);将JSON字符串回显到news.html中
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 import com.alibaba.fastjson.JSON;import javax.servlet.*;import javax.servlet.http.*;import javax.servlet.annotation.*;import java.io.IOException;import java.util.ArrayList;import java.util.List;@WebServlet(name = "NewsListServlet", value = "/news_list") public class NewsListServlet extends HttpServlet { @Override protected void doGet (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { List<News> list = new ArrayList <News>(); list.add(new News ("标题1" ,"2022-1-1" ,"TIOBE" ,"内容1" )); list.add(new News ("标题2" ,"2022-1-2" ,"TIOBE" ,"内容2" )); list.add(new News ("标题3" ,"2022-1-3" ,"TIOBE" ,"内容3" )); String newsjsonstr = JSON.toJSONString(list); System.out.println(newsjsonstr); response.setContentType("text/html;charset=UTF-8" ); response.getWriter().println(newsjsonstr); } @Override protected void doPost (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { } }
news.html:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 <!DOCTYPE html > <html lang ="en" > <head > <meta charset ="UTF-8" > <title > Insert title here</title > </head > <body > <div id ="container" > </div > <script > var xmlhttp; if (window .XMLHttpRequest ){ xmlhttp=new XMLHttpRequest (); }else { xmlhttp=new ActiveXObject ("Microsoft.XMLHTTP" ); } xmlhttp.open ("GET" ,"/ajax/news_list" ,true ); xmlhttp.send (); xmlhttp.onreadystatechange =function ( ){ if (xmlhttp.readyState == 4 && xmlhttp.status == 200 ){ var json = xmlhttp.responseText ; var jsont = JSON .parse (json); console .log (json); console .log (jsont); var html = "" ; for (var i =0 ;i<jsont.length ;i++){ var news = jsont[i]; html = html + "<h1>" +news.title +"</h1>" ; html = html + "<h2>" +news.date +" " +news.source +" " +news.content + "</h2>" ; html = html + "<hr/>" ; } document .getElementById ("container" ).innerHTML =html; } } </script > </body > </html >
效果:html中的ajax部分,会去请求访问Servlet,获取响应中的JSON字符串,在html中转变为JSON对象,按照需求来调用JSON对象中的属性
Ajax同步和异步的简述 在ajax的第二步,发送ajax请求的时候,第三个参数,true:异步;false同步
1 2 3 4 5 <script > xmlhttp.open ("GET" ,"/ajax/news_list" ,true ); xmlhttp.send (); </script >
那么什么是异步,什么是同步呢?
分析:xmlhttp.send();在发送请求的过程中是需要时间的,网络传输将请求发送到服务器,服务器处理后再返回响应的过程肯定是需要一些时间的
true异步:在上面发送请求的过程中,程序的其他部分继续向下执行;
false同步:在上面发送请求的过程中,程序的其他部分不继续向下执行,而是等到响应成功后再继续执行;
注意:
(1)ajax绝大部分情况下使用异步处理,但说不定某些场景适合使用同步的方式
(2)同步是发送一个请求,需要等待返回,然后才能够发送下一个请求;异步是发送一个请求,不需要等待返回,随时可以再发送下一个请求;同步有等待响应的过程
(3)同步和异步的深入理解必须通过实际应用中逐深渐化理解
同步与异步的区别 同步:同步可以看作是一个单线程操作,只要客户端请求了,在服务器没有回显之前都是线程阻塞的状态,不会向下执行任何操作,同步传输是面向比特的传输,他的单位是帧
异步:异步肯定是多线程,在客户端请求时,可以执行其他线程,并且把这个线程存放在他的队列里面,有序的执行,异步传输是面向字符的传输,他的单位是字符
示例一:设置为false同步 1 2 3 4 5 <script > xmlhttp.open ("GET" ,"/ajax/news_list" ,false ); xmlhttp.send (); console .log ("请求发送完成" ); </script >
在实际开发中,后台服务器响应需要一定的时间,为了使效果明显,方便肉眼观察,模拟后台实际消耗的时间,这里在servlet中写入休眠5秒
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 import com.alibaba.fastjson.JSON;import javax.servlet.*;import javax.servlet.http.*;import javax.servlet.annotation.*;import java.io.IOException;import java.util.ArrayList;import java.util.List;@WebServlet(name = "NewsListServlet", value = "/news_list") public class NewsListServlet extends HttpServlet { @Override protected void doGet (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { try { Thread.sleep(5000 ); }catch (InterruptedException e){ e.printStackTrace(); } List<News> list = new ArrayList <News>(); list.add(new News ("标题1" ,"2022-1-1" ,"TIOBE" ,"内容1" )); list.add(new News ("标题2" ,"2022-1-2" ,"TIOBE" ,"内容2" )); list.add(new News ("标题3" ,"2022-1-3" ,"TIOBE" ,"内容3" )); String newsjsonstr = JSON.toJSONString(list); System.out.println(newsjsonstr); response.setContentType("text/html;charset=UTF-8" ); response.getWriter().println(newsjsonstr); }
效果:发现,等后台响应后,html中的控制台才会输出预设的内容;但是,在浏览器界面没有显示出响应的结果,而是显示一个白板
一.为什么程序处于一直等待的状态;等待了差不多5秒后,才执行console.log(“请求发送完成”)
分析:在发送Ajax请求设置为false同步后,程序的其他部分不继续向下执行,而是等到服务器响应成功后再继续执行;send()方法会处于阻塞的状态,直到后台响应返回之后,才会向下执行,执行console.log()
二.为什么浏览器界面没有回显出相应的内容?
分析:这里是由Ajax的机制决定的,一旦这儿设置成false同步;在xmlhttp.onreadystatechanse = function(){}这个事件会失效
如果想在同步的情况下,继续在浏览器界面显示出响应内容:将xmlhttp.onreadystatechange = function(){}里面的内容复制到send()后面:也就是说xmlhttp.onreadystatechange = function(){}这个会不起作用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 =<!DOCTYPE html > <html > <head > <meta charset ="UTF-8" > <title > Insert title here</title > </head > <body > <div id ="container" > </div > <script > var xmlhttp; if (window .XMLHttpRequest ){ xmlhttp = new XMLHttpRequest (); }else { xmlhttp = new ActiveXObject ("Microsoft.XMLHTTP" ); } xmlhttp.open ("GET" ,"/ajax/news_list" ,false ); xmlhttp.send (); console .log ("请求发送完成" ); if (xmlhttp.readyState == 4 && xmlhttp.status == 200 ){ var t = xmlhttp.responseText ; var jsont = JSON .parse (t); console .log (t); console .log (jsont); var html = "" ; for (var i = 0 ;i< jsont.length ;i++){ var news = jsont[i]; html = html+"<h1>" +news.title +"</h1>" ; html = html + "<h2>" +news.date +" " +news.source +" " +news.content + "</h2>" ; html = html + "<hr/>" ; } document .getElementById ("container" ).innerHTML = html; }
效果:将失效的代码删除吗,直接复制到send()方法后面,等待5秒后回显到浏览器上
示例二:设置成true异步时:(核心内容) 异步:在网络发送请求的过程中不进行代码阻塞,继续向下执行,异步采用onreadstatechange进行对响应状态的监控,程序的其他部分同时进行
设置为异步案例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 <!DOCTYPE html > <html lang ="en" > <head > <meta charset ="UTF-8" > <title > Insert title here</title > </head > <body > <div id ="container" > </div > <script > var xmlhttp; if (window .XMLHttpRequest ){ xmlhttp=new XMLHttpRequest (); }else { xmlhttp=new ActiveXObject ("Microsoft.XMLHTTP" ); } xmlhttp.open ("GET" ,"/ajax/news_list" ,true ); xmlhttp.send (); console .log ("请求发送完成" ); xmlhttp.onreadystatechange =function ( ){ if (xmlhttp.readyState == 4 && xmlhttp.status == 200 ){ var json = xmlhttp.responseText ; var jsont = JSON .parse (json); console .log (json); console .log (jsont); var html = "" ; for (var i =0 ;i<jsont.length ;i++){ var news = jsont[i]; html = html + "<h1>" +news.title +"</h1>" ; html = html + "<h2>" +news.date +" " +news.source +" " +news.content + "</h2>" ; html = html + "<hr/>" ; } document .getElementById ("container" ).innerHTML =html; } } </script > </body > </html >
效果:可以看到,刷新界面后,控制台立即打印出”请求发送成功”,然后等待后台响应发送到html中回显;说明:当设置为异步后,请求发送后、响应回来前,程序会继续执行,只是xml.onreadystatechange = function(){}来实时监控响应的状态,程序可以通过此方法来按照不同的需求做出不同的程序