AJAX(Asynchronous Javascript And Xml)
学习AJAX的前提
-
能够完成需求:页面上有一个按钮,用户点击按钮之后,执行一段JS代码,再学习AJAX。
<script type="text/javascript"> // 页面加载完毕之后,给id="helloBtn"的元素绑定鼠标单击事件 // 这个function就是一个回调函数,这个回调函数什么时候执行?当load事件发生之后,这个回调函数才会执行。 // 什么是load事件?load事件什么时候发生?注意:页面加载完毕之后,load事件发生。 window.onload = function(){ function sayHello(){ alert("hello javascript") } // 获取id="helloBtn"的对象 var helloBtn = document.getElementById("helloBtn"); // 给id="helloBtn"元素绑定click事件 // 这个function也是一个回调函数,这个回调函数什么时候执行?当helloBtn被click的时候,被鼠标单击的时候,这个回调函数会执行。 // 鼠标单击五次,这个回调函数就会被调用五次。 helloBtn.onclick = function(){ // 回调函数中的this是发生事件的事件源对象。按钮对象发生了鼠标单击,那么this代表的就是这个按钮对象。 alert(this.value) } } </script> <!--第一种通过标签属性完成函数的调用--> <input type="button" value="hello" onclick="sayHello()"> <!--第二种通过JS代码给按钮绑定事件--> <input type="button" value="hello2" id="helloBtn">
AJAX 概述
-
AJAX不能称为一种技术,它是多种技术的综合产物。
-
AJAX可以让浏览器发送一种特殊的请求,这种请求可以是:异步的。
-
AJAX代码属于WEB前端的JS代码。和后端的java没有关系,后端可以是php语言,也可以是C语言。
-
AJAX 应用程序可以使用 XML 来传输数据,但将数据作为纯文本或 JSON 文本传输也同样常见。
-
AJAX可以更新网页的部分,而不需要重新加载整个页面。实现页面的局部刷新的效果
传统请求及缺点
-
传统的请求都有哪些?
-
直接在浏览器地址栏上输入URL。
-
通过点击超链接发起请求
<!--超链接相当于在地址栏上输入URL , 需要带项目名old--> <a href="/old/request">传统请求(超链接)</a>
-
通过提交form表单发起请求
<!--action指定请求的URL , method指定请求的方式 , 默认发起get请求 --> <form action="/old/request" method="get"> <input type="submit" value="传统请求(form表单提交)"> </form>
-
通过使用JS代码发送请求
<!--通过JS代码来发送请求--> <input type="button" value="传统请求(通过JS代码发送请求)" onclick="sendRequest()"> <script type="text/javascript"> function sendRequest(){ // 发送请求 //window.open(url) //window.location.href = "" document.location.href = "/old/request" } </script>
后端处理请求的代码
//使用注解的方式指定请求路径和Servlet类之间的关系,不带项目名 @WebServlet("/request") public class OldRequestServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 响应信息到浏览器 response.setContentType("text/html;charset=UTF-8"); PrintWriter out = response.getWriter(); // 向浏览器输出HTML代码,浏览器接收到HTML代码之后渲染页面,展现页面给用户。 out.print("<h1>欢迎学习AJAX。。。。</h1>"); } }
-
-
传统请求存在的问题
-
浏览器会将当前页面内容全部清空 , 然后根据服务器的响应内容(HTML ,CSS , JS)重新渲染一个新的页面 , 导致用户的体验较差。
-
传统的请求导致用户的体验有空白期。(用户的体验是不连贯的)
-
AJAX请求的同步和异步
-
什么是异步,什么是同步?
-
ajax请求1和ajax请求2,同时并发,谁也不用等谁,这就是异步。
-
如果ajax请求1在发送的时候需要等待ajax请求2结束之后才能发送,那么这就是同步。(a等待b,或者b等待a,只要发生等待,就是同步。)
-
-
AJAX是可以发送异步请求的。也就是说,在同一个浏览器页面当中,可以发送多个ajax请求,这些ajax请求之间不需要等待,是并发的。
- AJAX可以做到在同一个网页中同时启动多个请求,类似于在同一个网页中启动“多线程”,一个“线程”对应一个“请求”。
-
异步和同步在代码上的实现
// 打开通道 // true表示该请求支持异步,即我这个请求发送之后,不影响其他ajax请求的发送。 // false表示该请求不支持异步。即我这个请求发了之后,你们其他的请求都要靠边站。都等着。等我结束了你们才能发送。 xhr.open("请求方式", "URL", true/false) // 发起请求 xhr.send()
前端代码
<script type="text/javascript"> window.onload = function(){ //发送ajax请求1 document.getElementById("btn1").onclick = function (){ var xhr = new XMLHttpRequest(); xhr.onreadystatechange = function (){ if (this.readyState == 4) { if (this.status == 200) { document.getElementById("div1").innerHTML = this.responseText }else{ alert(this.status) } } } // 我不支持异步了,我这个请求只要发,你们都得靠边站。都得等着我结束你们才能发请求。 xhr.open("GET", "/ajax/ajaxrequest1?t=" + new Date().getTime(), false) xhr.send() } //发送ajax请求2 document.getElementById("btn2").onclick = function (){ var xhr = new XMLHttpRequest(); xhr.onreadystatechange = function (){ if (this.readyState == 4) { if (this.status == 200) { document.getElementById("div2").innerHTML = this.responseText }else{ alert(this.status) } } } xhr.open("GET", "/ajax/ajaxrequest2?t=" + new Date().getTime(), true) xhr.send() } } </script> <button id="btn1">ajax请求1</button> <div id="div1"></div> <button id="btn2">ajax请求2</button> <div id="div2"></div>
后端代码
//对应ajax请求1 @WebServlet("/ajaxrequest1") public class AjaxRequest8ervlet extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { try { //当我这个请求发送时 , 其他异步请求都要等待10S才能发送请求 Thread.sleep(10 * 1000); } catch (InterruptedException e) { e.printStackTrace(); } response.setContentType("text/html;charset=UTF-8"); response.getWriter().print("ajax请求1"); } } //对应ajax请求2 @WebServlet("/ajaxrequest2") public class AjaxRequest9Servlet extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=UTF-8"); response.getWriter().print("ajax请求2"); } }
-
用户注册的时候 , 发送ajax请求校验信息的时候需要使用同步(大部分情况下我们都是使用ajax异步方式,同步很少用)
-
用户在填写注册信息的时候 , 填写完用户名需要发送ajax请求进行校验 , 填完用户密码等其他信息都需要发送ajax请求校验等
-
并且最终点击注册按钮的时候,也是发送ajax请求进行注册。
-
那么显然,注册的Ajax请求和校验的ajax请求不能异步,必须等待所有的校验ajax请求结束之后,注册的ajax请求才能发。
-
XMLHttpRequest对象的属性和方法
-
XMLHttpRequest对象是AJAX的核心对象,发送请求以及接收服务器数据的返回,全靠它了。
-
XMLHttpRequest对象,现在浏览器都是支持的,都内置了该对象。直接用即可。
-
创建XMLHttpRequest对象
var xhr = new XMLHttpRequest();
-
XMLHttpRequest对象的方法
方法 | 描述 |
---|---|
abort() | 取消当前请求 |
getAllResponseHeaders() | 返回头部信息 |
getResponseHeader() | 返回特定的头部信息 |
open(method, url, async, user, psw) | 规定请求method:请求类型 GET 或 POSTurl:文件位置async:true(异步)或 false(同步)user:可选的用户名称psw:可选的密码 |
send() | 将请求发送到服务器,用于 GET 请求 |
send(string) | 将请求发送到服务器,用于 POST 请求 |
setRequestHeader() | 向要发送的报头添加标签/值对 |
- XMLHttpRequest对象的属性
属性 | 描述 |
---|---|
onreadystatechange | 定义当 readyState 属性发生变化时被调用的函数 |
readyState | 保存 XMLHttpRequest 对象请求到响应过程中的状态 , 表示完成的进度 。0:请求未初始化 1:服务器连接已建立 2:请求已收到 3:正在处理请求 4:请求已完成且响应也已完成 |
responseText | 以字符串返回响应数据 |
responseXML | 以 XML 数据返回响应数据 |
status | 服务器响应结束后, 一般会返回请求的状态号 , 用来表示响应的结果 , 即完成的怎么样200: “OK” , 403: “Forbidden” , 404: “Not Found” |
statusText | 返回状态文本(比如 “OK” 或 “Not Found”) |
- XMLHttpRequest对象的readyState属性
解决AJAX发请求时的乱码问题
-
对于tomcat10来说,关于字符集,我们程序员不需要干涉,无论发送什么请求 , 无论是服务器还是浏览器 都不会出现乱码问题。
-
对于tomcat9及之前的版本 , 服务器响应中文的时候会出现乱码 , 发送ajax post请求的时候,服务器接收也会乱码
-
发送ajax get请求
- 服务器获取请求提交的数据不会出现乱码
- 服务器响应给前端的中文会乱码 , 必须设置响应对象的charset=UTF-8属性
@Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 服务器接收的中文不会出现乱码 String username = request.getParameter("username"); System.out.println(username); // 服务器响应到浏览器的中文会有乱码 , 必须设置charset=UTF-8属性 response.setContentType("text/html;charset=UTF-8"); // tomcat9以及之前的版本,这行代码是必须要加的。 PrintWriter out = response.getWriter(); out.print(username);
-
发送ajax post请求
- 服务器获取请求提交的数据会出现乱码 , 必须设置请求对象的charset=UTF-8属性
- 服务器响应给前端的中文会乱码 ,必须设置响应对象的charset=UTF-8属性
@Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 接收的中文也会出现乱码 , 通过request对象设置charset=UTF-8属性 request.setCharacterEncoding("UTF-8"); String username = request.getParameter("username"); System.out.println(username); // 服务器响应到浏览器的中文会有乱码 , 通过response对象设置charset=UTF-8属性 response.setContentType("text/html;charset=UTF-8"); PrintWriter out = response.getWriter(); out.print(username); }