Ajax
Ajax
AJAX = Asynchronous JavaScript and XML(异步的JavaScript和 XML)。
Ajax 不是一种新的编程语言,而是一种用于创建更好更快以及交互性更强的Web应用程序的技术。
C/S
增加B/S的体验性
B/S: 未来的主流,并且会爆发式的持续增长;
产品链:H5+网页+客户端+手机端(Android, IOS) +小程序
使用jQuery需要先导入jQuery的js文件;
1.原理图解
AJAX = Asynchronous JavaScript and XML(异步的JavaScript和 XML)。
AJAX可以在浏览器当中发送异步请求。请求A和请求B是异步的。谁也不需要等谁,类似于多线程并发。
AJAX的请求发送之后,不会出现页面清空,然后展示新页面的效果。AJAX不是这样的。
这个图想表示的最核心的是:AJAX请求1和AJAX请求2是异步的。并发的,谁也不干扰谁。
浏览器上发送AJAX请求,这些代码是JS语法的代码。其实发送AJAX请求,就是需要编写JS代码的。
2.异步,同步
什么是异步,什么是同步?
- 假设有t1和t2线程,t1和t2线程并发,就是异步。
- 假设有t1和t2线程,t2在执行的时候,必须等待t1线程执行到某个位置之后t2才能执行,那么t2在等t1,显然他们是排队的,排队的就是同步。
- AJAX是可以发送异步请求的。也就是说,在同一个浏览器页面当中,可以发送多个AJAX请求,这些AJAX请求之间不需要等待,是并发的。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <script> function sayHello() { alert("Hello,world!"); } </script> <!--需求:页面上有一个按钮,用户点击按钮之后,执行一段JS代码--> <input type="button" value="hello" onclick="sayHello()"> <!--通过JS代码给按钮绑定事件--> <input type="button" value="hello2" id="helloBtn"> <script type="text/javascript"> //页面加载完毕之后,给id="helloBtn"的元素绑定鼠标单击事件 //这个function就是一个回调函数,这个回调函数什么时候执行?当load事件发生之后, // 这个回调函数才会执行。 //什么是load事件?load事件什么时候发生? 注意:页面加载完毕之后,load事件发生。 window.onload = function (){ //获取id="helloBtn"的对象 var helloBtn = document.getElementById("helloBtn"); //给id="helloBtn"元素绑定click事件 //这个function也是一个回调函数,这个回调函数什么时候执行? //当helloBtn被click的时候,被鼠标单击的时候,这个回调函数会执行。 //鼠标单击五次,这个回调函数就会被调用五次。 helloBtn.onclick = function (){ // alert("hello javaScript2"); //alert(this) //这个回调函数中的this是谁呢? //this是发生事件的事件源对象。是按钮发生了鼠标单击,那么this代表的就是这个按钮对象。 alert(this.value); } } </script> </body> </html>
在AJAX的请求,以及AJAX接收服务器的响应,完全都是依靠XMLHttpRequest对象的。
XMLHttpRequest对象中的readyState属性记录下XMLHttpRequest对象的状态。
XMLHttpRequest对象的readyState属性对应的状态值:
0:请求未初始化
1:服务器连接已建立
2:请求已收到
3:正在处理请求
4:请求已完成且响应已就绪
当XMLHttpRequest对象的readyState属性的值变成4的时候,表示这个AJAX请求以及响应已经全部完成了。
3.第一个Ajax程序
package com.feng; import javax.servlet.annotation.WebServlet; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.PrintWriter; @WebServlet("/ajaxrequest1") public class AjaxRequest1Servlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //String s = null; //s.toString(); // Servlet向浏览器响应一段数据 PrintWriter out = resp.getWriter(); //out对象向浏览器输出信息 //服务器的代码实际上和以前的代码还是完全一样的。 //只不过这个out在响应的时候,浏览器客户端的XMLHttpRequest对象会接收到这个响应的信息。 out.print("welcome to study ajax!!!"); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req, resp); } }
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <script type="text/javascript"> window.onload = function () { document.getElementById("helloBtn").onclick = function () { //发送ajax get请求 // console.log("发送ajax get请求"); //1.第一步:创建AJAX核心对象XMLHttpRequest var xhr = new XMLHttpRequest(); //2.第二步:注册回调函数 //这是一个回调函数, // 这个函数在XMLHttpRequest对象的readyState状态值发生改变的时候被调用。 xhr.onreadystatechange = function (){ //这里的回调函数会被调用多次。 //0 -> 1 被调用一次 //1 -> 2 被调用一次 //2 -> 3 被调用一次 //3 -> 4 被调用一次 // console.log(xhr.readyState); //当XMLHttpRequest对象的readyState的状态是4的时候,表示响应结束了。 // if(xhr.readyState == 4){ // // } if(this.readyState == 4){ //响应结束了 // console.log("响应结束了"); //响应结束之后,一般会有一个HTTP的状态码。 //HTTP状态码常见的包括:200表示成功了,404表示资源找不到,500表示服务器内部错误。 //HTTP状态码是HTTP协议的一部分,HTTP协议中规定的。服务器响应之后都会有一个状态码。 //获取HTTP状态码 // console.log("HTTP响应状态码:" +this.status); if(this.status == 404){ alert("对不起,您访问的资源不存在,请检查请求路径"); }else if(this.status == 500){ alert("对不起,服务器发生了严重的内部错误,请联系管理员"); }else if(this.status == 200){ // alert("响应成功,完美"); // 200表示完全响应完毕,成功结束了。 // 通过XMLHttpRequest对象获取响应的信息。 // 通过XMLHttpRequest对象的responseText属性来获取响应的信息。 // alert(this.responseText) //把响应信息放到div图层当中,渲染 document.getElementById("mydiv").innerHTML = this.responseText; } } } //3.第三步:开启通道(open只是浏览器和服务器建立连接,通道打开,并不会发送请求) //XMLHttpRequest对象的open方法 //open(method,url,async,user,psw) //method:请求的方式,可以是GET,也可以是POST,也可以是其它请求方式。 //url:请求的路径 //async:只能是true或者false,true表示此ajax请求是一个异步请求, // false表示此ajax请求是一个同步请求, //(大部分请求都是true,要求异步。极少数情况需要同步) //user: 用户名 pwd:密码,用户名和密码是进行身份认证的,说明要想访问这个服务器上的资源, // 可能需要提供一些口令才能访问。需不需要用户名和密码,主要看服务器的态度。 xhr.open("GET","/ajax1/ajaxrequest1",true); //4.第四步:发送请求 xhr.send(); } } </script> <!--给一个按钮,用户点击这个按钮的时候发送ajax请求--> <input type="button" value="hello ajax" id="helloBtn"> <!--给一个div图层,ajax接收了响应的数据之后,在div中进行渲染--> <div id="mydiv"></div> </body> </html>
<dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.11</version> <scope>test</scope> </dependency> <dependency> <groupId>javax.servlet.jsp</groupId> <artifactId>jsp-api</artifactId> <version>2.2</version> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> <version>2.5</version> </dependency> <dependency> <groupId>org.apache.tomcat.embed</groupId> <artifactId>tomcat-embed-core</artifactId> <version>9.0.58</version> </dependency> </dependencies>
4.AJAX GET请求
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>发送ajax get请求</title> </head> <body> <script type="text/javascript"> window.onload = function (){ document.getElementById("btn").onclick = function (){ //1.创建AJAX核心对象 var xhr = new XMLHttpRequest(); //2.注册回调函数 xhr.onreadystatechange = function (){ if(this.readyState == 4){ debugger if(this.status == 200){ //通过XMLHttpRequest对象的responseText属性可以获取到服务器响应回来的内容。 //并且不管服务器响应回来的是什么, // 都以普通文本的形式获取。(服务器可能响应回来:普通文本, XML,JSON,HTML...) // innerHTML属性是javascript中的语法,和ajax的XMLHttpRequest对象无关。 // innerHTML可以设置元素内部的HTML代码。(innerHTMl可以将后面的内容当做一段HTML代码解释并执行) document.getElementById("myspan").innerHTML = this.responseText; }else{ alert(this.status) } } } //3. 开启通道 xhr.open("GET","/ajax1/ajaxrequest2",true); //4.发送请求 xhr.send(); } } </script> <button id="btn">发送ajax get请求</button> <span id="myspan"></span> </body> </html>
package com.feng; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.PrintWriter; /** * @auther fengpeng * @date 2022/9/4 */ @WebServlet("/ajaxrequest2") public class AjaxRequest2Servlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //设置响应的内容类型以及字符集 resp.setContentType("text/html;charset=UTF-8"); //获取响应流 PrintWriter out = resp.getWriter(); //响应 out.print("<font color='red'>用户名已存在!!!</font>"); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req, resp); } }
- AJAX get请求如何提交数据呢?
- get请求提交数据是在"请求行"上提交,格式是: url?name=value&name=value&name=value...
- 其实这个get请求提交数据的格式是HTTP协议中规定的,遵循协议即可。
提交数据
//3. 开启通道 // 获取到用户填写的usercode和username var usercode = document.getElementById("usercode").value; var username = document.getElementById("username").value; xhr.open("GET","/ajax1/ajaxrequest2?usercode="+usercode+"&username="+username,true); //4.发送请求 xhr.send(); } } </script> usercode<input type="text" id="usercode"><br> username<input type="text" id="username"><br> <button id="btn">发送ajax get请求</button> <span id="myspan"></span> </body>
5.AJAX GET请求的缓存问题
-
对于低版本的IE浏览器来说,AJAX的get请求可能会走缓存。存在缓存问题。
-
对于现代的浏览器来说,大部分浏览器都不存在AJAX get缓存问题了。
-
什么是AJAX GET请求缓存问题呢?
- 在HTTP协议中是这样规定get请求的:get请求会被缓存起来。
- 发送AJAX GET请求时,在同一个浏览器上,前后发送的AJAX请求路径一样的话,对于低版本的IE来说,第二次的AJAX GETq请求会走缓存,不走服务器。
-
POST请求在HTTP协议中规定的是:POST请求不会被浏览器缓存。
-
GET请求缓存的优缺点:
- 优点:直接从浏览器缓存中获取资源,不需要从服务器上重新加载资源,速度较快,用户体验好。
- 缺点:无法实时获取最新的服务器资源。
-
浏览器什么时候会走缓存?
- 第一:是一个GET请求
- 第二:请求路径已经被浏览器缓存过了。第二次发送请求的时候,这个路径没有变化,会走浏览器缓存。
-
如果是低版本的IE浏览器,怎么解决AJAX GET请求的缓存问题呢?
- 可以在请求路径url后面添加一个时间戳,这个时间戳是随时变化的。所以每一次发送的请求路径都是不一样的,这样就不会走浏览器的缓存问题了。
- 可以采用时间戳:"url?t=" + new Date().getTime()
- 或者可以通过随机数:"url?t=" + Math.random()
- 也可以随机数+时间戳...
6.AJAX POST请求
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>发送ajax post请求</title> </head> <body> <script> window.onload = function (){ document.getElementById("mybtn").onclick = function (){ // 发送AJAX POST请求 // 1.创建AJAX核心对象 var xhr = new XMLHttpRequest(); // 2.注册回调函数 xhr.onreadystatechange = function (){ if (this.readyState == 4) { if(this.status == 200){ document.getElementById("mydiv").innerHTML = this.responseText }else{ alert(this.status) } } } // 3.开启通道 xhr.open("POST","/ajax1/ajaxrequest3",true); // 4.发送请求 xhr.send(); } } </script> <button id="mybtn" >发送AJAX POST请求</button> <div id="mydiv"></div> </body> </html>
package com.feng; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.PrintWriter; /** * @auther fengpeng * @date 2022/9/5 */ @WebServlet("/ajaxrequest3") public class AjaxRequest3Servlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { resp.setContentType("text/html;charset=UTF-8"); PrintWriter out = resp.getWriter(); out.print("<font color='red'>用户名已存在!!!</font>"); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req, resp); } }
7.AJAX POST请求模拟表单提交数据
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>发送ajax post请求</title> </head> <body> <script> window.onload = function (){ document.getElementById("mybtn").onclick = function (){ // 发送AJAX POST请求 // 1.创建AJAX核心对象 var xhr = new XMLHttpRequest(); // 2.注册回调函数 xhr.onreadystatechange = function (){ if (this.readyState == 4) { if(this.status == 200){ document.getElementById("mydiv").innerHTML = this.responseText }else{ alert(this.status) } } } // 3.开启通道 xhr.open("POST","/ajax1/ajaxrequest3",true); // 4.发送请求 // 怎么模拟AJAX提交form表单呢? 设置请求头的内容类型 // (这行代码非常关键,是模拟form表单提交的关键代码。) // 设置请求头的内容类型时,必须在open之后。 xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded") // 放到send()这个函数的小括号当中的数据,会自动在请求体当中提交数据。 // 使用JS代码获取用户填写的用户名和密码 var username = document.getElementById("username").value; var password = document.getElementById("password").value; //xhr.send("注意格式: 放在这里的数据就是在请求体当中提交的,格式不能随便来, // 还是需要遵循HTTP的协议:name=value&name=value&name=value) xhr.send("username="+username+"&password="+password); } } </script> 用户名<input type="text" id="username"><br> 密码<input type="password" id="password"><br> <button id="mybtn" >发送AJAX POST请求</button> <div id="mydiv"></div> </body> </html>
package com.feng; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.PrintWriter; /** * @auther fengpeng * @date 2022/9/5 */ @WebServlet("/ajaxrequest3") public class AjaxRequest3Servlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { resp.setContentType("text/html;charset=UTF-8"); PrintWriter out = resp.getWriter(); //out.print("<font color='red'>用户名已存在!!!</font>"); // 获取提交数据 String username = req.getParameter("username"); String password = req.getParameter("password"); out.print("用户名是:"+username+",密码是:"+password); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req, resp); } }
- AJAX POST请求和GET请求的代码区别在哪里?就是前端代码有区别。后端代码没有区别。
//4.发送AJAX POST请求 xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded") //获取表单中的数据 var username = document.getElementById("username").value; var password = document.getElementById("password").value; //send函数中的参数就是发送的数据,这个数据在"请求体"当中发送。 xhr.send("username"+ username+"&password"+ password)
- 实现一个案例:使用AJAX POST请求实现用户注册的时候,用户名是否可用。(验证用户名是否可以注册),实现步骤如下:
- 在前端,用户输入用户名之后,失去焦点事件blur发生,然后发送AJAX POST请求,提交用户名
- 在后端,接收到用户名,连接数据库,根据用户名去表中搜索
- 如果用户名已存在
- 后端响应消息:对不起,用户名已存在(在前端页面以红色字体展示)
- 如果用户名不存在
- 后端响应消息:用户名可以使用(在前端页面以绿色字体展示)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>AJAX POST请求验证用户名是否可用</title> </head> <body> <script type="text/javascript"> window.onload = function (){ document.getElementById("username").onfocus = function (){ document.getElementById("tipMsg").innerHTML = ""; } document.getElementById("username").onblur = function (){ // console.log("正在发送AJAX POST请求验证用户名 ") //发送AJAX POST请求 //1. var xhr = new XMLHttpRequest(); //2. xhr.onreadystatechange = function (){ if (this.readyState == 4) { if(this.status == 200){ document.getElementById("tipMsg").innerHTML = this.responseText }else { alert(this.status) } } } //3. xhr.open("POST","/ajax1/ajaxrequest4",true) //4. xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded") // 获取表单数据 var username = document.getElementById("username").value; xhr.send("username="+ username) } } </script> 用户名:<input type="text" id="username"> <span id="tipMsg"></span> </body> </html>
package com.feng; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.PrintWriter; import java.sql.*; /** * @auther fengpeng * @date 2022/9/12 */ @WebServlet("/ajaxrequest4") public class AjaxRequest4Servlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //获取用户名 String username = req.getParameter("username"); // 打布尔标记(一种编程模型) boolean flag = false; // 默认是用户名不存在 //连接数据库验证用户名是否存在 Connection conn = null; PreparedStatement ps = null; ResultSet rs = null; try { // 1.注册驱动 Class.forName("com.mysql.cj.jdbc.Driver"); // 2.获取连接 conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/mybatis?useUnicode=true&characterEncoding=utf8&serverTimezone=UTC","root","fp"); // 3.获取预编译的数据库操作对象 String sql = "select * from mybatis.t_user where name = ?"; ps = conn.prepareStatement(sql); ps.setString(1,username); // 4.执行SQL语句 rs = ps.executeQuery(); // 5.处理结果集 if (rs.next()) { // 用户名已存在。 flag = true; } } catch (Exception e) { e.printStackTrace(); }finally { // 6.释放资源 if (rs != null) { try { rs.close(); } catch (SQLException throwables) { throwables.printStackTrace(); } } if (ps != null) { try { ps.close(); } catch (SQLException throwables) { throwables.printStackTrace(); } } if (conn != null) { try { conn.close(); } catch (SQLException throwables) { throwables.printStackTrace(); } } } //响应结果到浏览器 resp.setContentType("text/html;charset=UTF-8"); PrintWriter out = resp.getWriter(); if (flag) { //用户名已存在,不可用 out.print("<font color='red'>对不起,用户名已存在</font>"); }else { // 用户名不存在,可以使用 out.print("<font color='green'>用户名可以使用</font>"); } } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req, resp); } }
8.创建json对象
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>json test</title> </head> <body> <script type="text/javascript"> // 在javascript语言中怎么创建一个json对象呢? 语法是什么? // var jsonobj = { // "属性名1" : 属性值, // "属性名2" : 属性值, // "属性名3" : 属性值, // "属性名4" : 属性值, // "属性名5" : 属性值 // } // // 注意: // 属性值的数据类型,那就随意了。可能是数字,可能是布尔类型,可能是字符串,可能是数组.... // 另一个json对象 var address = { "city" : "北京", "street" : "北京大兴区", "zipcode" : "123456" } var user = { "usercode" : 111, "username" : "zhangsan", "sex" : true, "age" : 20, "hobbies" : ["抽烟","喝酒","烫头"], "addr" : address } // 访问json对象的属性 // 第一种方式 console.log(user.username) console.log(user.usercode) console.log(user.sex ? "男" : "女") console.log(user.age) for (var i = 0; i < user.hobbies.length ; i++) { console.log(user.hobbies[i]) } // 访问这个用户是哪个街道的? console.log(user.addr.street) //第二种方式 console.log(user["usercode"]) console.log(user["username"]) console.log(user["sex"] ? "男的" : "女的") console.log(user["age"]) </script> </body> </html>
基于JSON的数据交换
- 在WEB前端中,如何将一个json格式的字符串转换成json对象
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>json test2</title> </head> <body> <script type="text/javascript"> // 这是一个json对象 var user = { "username" : "zhangsan", "password" : "123456" } // 是json对象,才能这样访问。 alert(user.username + "," +user.password) // 从服务器端返回来的不是一个json对象,是一个json格式的字符串 , \转义字符 var fromJavaServerJsonStr = "{\"usercode\" : 111, \"age\" : 20}" // 有两种方式: // 第一种方式:使用eval函数。(javascript中的内容) // 第二种方式:调用javascript语言中的内置对象JSON的一个方法parse var jsonobj = JSON.parse(fromJavaServerJsonStr); alert(jsonobj.usercode + "," +jsonobj.age) </script> </body> </html>
9.连接数据库动态拼接JSON字符串
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>发送AJAX请求,显示学生列表</title> </head> <body> <script type="text/javascript"> window.onload = function (){ document.getElementById("btn").onclick = function(){ // 1.创建核心对象 var xhr = new XMLHttpRequest(); // 2.注册回调函数 xhr.onreadystatechange = function (){ if (this.readyState == 4) { if (this.status == 200) { // document.getElementById("stutbody").innerHTML = this.responseText // 将json格式的字符串转换成json对象 var stuList = JSON.parse(this.responseText);// 是一个数组,并且数组中有多个学生数据 var html = "" for (var i = 0; i < stuList.length; i++) { var stu = stuList[i] html += "<tr>" html += "<td>"+(i+1)+"</td>" html += "<td>"+stu.name+"</td>" html += "<td>"+stu.age+"</td>" html += "<td>"+stu.addr+"</td>" html += "</tr>" } document.getElementById("stutbody").innerHTML = html }else{ alert(this.status) } } } // 3.开启通道 xhr.open("GET","/ajax1/ajaxrequest5",true) // 4.发送请求 xhr.send() } } </script> <input type="button" value="显示学员列表" id="btn"> <table width="50%" border="1px"> <thead> <tr> <th>序号</th> <th>姓名</th> <th>年龄</th> <th>住址</th> </tr> </thead> <tbody id="stutbody"> <!--<tr>--> <!-- <td>1</td>--> <!-- <td>张三</td>--> <!-- <td>20</td>--> <!-- <td>北京大兴区</td>--> <!--</tr>--> <!--<tr>--> <!-- <td>2</td>--> <!-- <td>李四</td>--> <!-- <td>22</td>--> <!-- <td>北京海淀区</td>--> <!--</tr>--> </tbody> </table> </body> </html>
package com.feng; import javax.jws.WebService; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.PrintWriter; import java.sql.*; /** * @auther fengpeng * @date 2022/9/12 */ @WebServlet("/ajaxrequest5") public class AjaxRequest5Servlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //连接数据库,查询学员信息,拼接HTML代码,响应HTML代码到浏览器(这里就不再连接数据库了,写死了) resp.setContentType("text/html;charset=UTF-8"); PrintWriter out = resp.getWriter(); //连接数据库,拼接HTML代码 StringBuilder html = new StringBuilder(); // 目前存在的缺点:在后端的java代码中又开始拼接HTML代码了。显然这是在后端java中写前端的HTML代码。不好维护。 // 能不能直接将数据返回,给WEB前端数据就行了。让WEB前端能够拿到数据就行,然后页面展示的功能交给WEB前端来处理。 // 我们后端的java代码能不能只返回数据???可以。(返回数据可以采用JSON的格式,也可以采用XML的格式) // html.append("<tr>"); // html.append("<td>1</td>"); // html.append("<td>张三</td>"); // html.append("<td>20</td>"); // html.append("<td>北京大兴区</td>"); // html.append("</tr>"); // html.append("<tr>"); // html.append("<td>2</td>"); // html.append("<td>李四</td>"); // html.append("<td>22</td>"); // html.append("<td>北京海淀区</td>"); // html.append("</tr>"); // //out.print(html); // 将以上程序拼接HTML,换成拼接JSON格式的字符串 //String jsonStr = "[{\"name\":\"王五\",\"age\":20,\"addr\":\"北京大兴区\"},{\"name\":\"李四\",\"age\":22,\"addr\":\"北京海淀区\"}]"; // 准备StringBuilder对象,拼接JSON StringBuilder json = new StringBuilder(); String jsonStr = ""; // 连接数据库,查询所有的学生,拼接json字符串 Connection conn = null; PreparedStatement ps = null; ResultSet rs = null; try { // 1.注册驱动 Class.forName("com.mysql.cj.jdbc.Driver"); // 2.获取连接 conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/mybatis?useUnicode=true&characterEncoding=utf8&serverTimezone=UTC","root","fp"); // 3.获取预编译的数据库操作对象 String sql = "select name,age,addr from mybatis.t_student"; ps = conn.prepareStatement(sql); // 4.执行SQL语句 rs = ps.executeQuery(); json.append("["); // 5.处理结果集 while(rs.next()) { // 获取每个学生的信息 String name = rs.getString("name"); String age = rs.getString("age"); String addr = rs.getString("addr"); // 拼接json格式的字符串 // {"name":" 王五 ","age": 20 ,"addr":" 北京大兴区 "} json.append("{\"name\":\""); json.append(name); json.append("\",\"age\":"); json.append(age); json.append(" ,\"addr\":\""); json.append(addr); json.append("\"},"); } jsonStr = json.substring(0,json.length()-1) + "]"; } catch (Exception e) { e.printStackTrace(); }finally { // 6.释放资源 if (rs != null) { try { rs.close(); } catch (SQLException throwables) { throwables.printStackTrace(); } } if (ps != null) { try { ps.close(); } catch (SQLException throwables) { throwables.printStackTrace(); } } if (conn != null) { try { conn.close(); } catch (SQLException throwables) { throwables.printStackTrace(); } } } //响应JSON格式的字符串给前端。/ out.print(jsonStr); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req, resp); } }
10.fastjson
package com.feng.fastjson; import com.alibaba.fastjson.JSON; import java.util.ArrayList; import java.util.List; public class FastjsonTest { public static void main(String[] args) { //创建一个User类型的对象 User user = new User("111", "zhangsan", 20); //将以上的User对象转换为json格式的字符串 //使用阿里巴巴的fastjson组件中的JSON类即可。 //fastjson中又一个类,叫做:JSON。全部大写。 //JSON类中的方法都是静态的方法,直接调用即可。 String jsonstr = JSON.toJSONString(user); System.out.println(jsonstr); //尝试List集合是否可以转换成数组 List<User> userList = new ArrayList<>(); User user1 = new User("111", "lisi", 20); User user2 = new User("111", "wangwu", 20); userList.add(user1); userList.add(user2); String jsonStr2 = JSON.toJSONString(userList); System.out.println(jsonStr2); } }
11.基于XML的数据交换
- 注意:如果服务器端响应XML的话,响应的内容类型需要写成:
resp.setContentType("text/xml;charset=utf-8");
- xml和JSON都是常用的数据交换格式
- XML体积大,解析麻烦,较少用。
- JSON体积小,解析简单,较常用。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>使用XML完成数据交换</title> </head> <body> <script type="text/javascript"> window.onload = function (){ document.getElementById("btn").onclick = function (){ //1.创建XMLHttpRequest对象 var xhr = new XMLHttpRequest(); //2.注册回调函数 xhr.onreadystatechange = function (){ if (this.readyState == 4) { if (this.status == 200) { //服务器端响应了一个XML字符串,这里怎么接收呢? //使用XMLHttpRequest对象的responseXML属性,接收返回之后,可以自动封装成document对象(文档对象) var xmlDoc = this.responseXML // console.log(xmlDoc) //获取所有的<student>元素,返回了多个对象,应该是数组。 var students = xmlDoc.getElementsByTagName("student") // console.log(student[0].nodeName) var html = '' for (var i = 0; i < students.length; i++) { var student = students[i] //获取<student>元素下的所有子元素 html+="<tr>" html+="<td>" +(i+1)+"</td>" var nameOrAge = student.childNodes for (var j = 0; j < nameOrAge; j++) { var node = nameOrAge[j] if (node.nodeName = "name") { html += "<td>" +node.textContent+"</td>" } if (node.nodeName == "age") { html += "<td>" +node.textContent+"</td>" } } html += "</tr>" } document.getElementById("stutbody").innerHTML = html }else { alert(this.status) } } } //3.开启通道 xhr.open("GET","/f/ajaxrequest6",true); //4.发送请求 xhr.send(); } } </script> <button id="btn">显示学生列表</button> <table width="500px" border="1px"> <thead> <tr> <th>序号</th> <th>姓名</th> <th>年龄</th> </tr> </thead> <tbody id="stutbody"> <tr> <td>1</td> <td>zhangsan</td> <td>20</td> </tr> <tr> <td>2</td> <td>lisi</td> <td>22</td> </tr> </tbody> </table> </body> </html>
package com.feng.fastjson; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.PrintWriter; /** * @Author feng peng * @Date 2022/10/4 * @Time 9:13 */ @WebServlet("/ajaxrequest6") public class AjaxRequest6Servlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //注意:响应的内容类型是XML。 resp.setContentType("text/xml;charset=UTF-8"); PrintWriter out = resp.getWriter(); /* * <students> <student> * <name>zhangsan</name> * <age>20</age> * </student> * </student> *<students> <student> * <name>lisi</name> * <age>22</age> * </student> * </student> * * */ StringBuilder xml = new StringBuilder(); xml.append("<students>"); xml.append("student>"); xml.append("<name>zhangsan</name>"); xml.append("<age>20</age>"); xml.append("</student>"); xml.append("</students>"); xml.append("<students>"); xml.append("student>"); xml.append("<name>lisi</name>"); xml.append("<age>22</age>"); xml.append("</student>"); xml.append("</students>"); out.print(xml); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req, resp); } }
12.AJAX乱码问题
-
测试内容:
- 发送ajax get请求
- 发送数据到服务器,服务器获取的数据是否乱码?
- 服务器响应给前端的中文,会不会乱码?
- 发送ajax post请求
- 发送数据到服务器,服务器获取的数据是否乱码?
- 服务器响应给前端的中文,会不会乱码?
- 发送ajax get请求
-
包括还要测试tomcat服务器的版本:
-
tomcat9 测试。
- 响应中文的时候,会出现乱码,怎么解决?
response.setContentType("text/html;charset=UTF-8"); - 发送ajax post请求的时候,发送给服务器的数据,服务器接收之后乱码,怎么解决?
request.setCharacterEncoding("UTF-8");
-
13.AJAX的异步和同步
- 什么是异步?什么是同步?
- ajax请求1和ajax请求2,同时并发,谁也不用等谁,这就是异步。(a不等b,b也不等a)
- 如果ajax请求1在发送的时候需要等待ajax请求2结束之后才能发送,那么这就是同步。(a等待b,或者b等待a,只要发生等待,就是同步。)
- 异步和同步在代码如何实现?
//假设这个是ajax请求1 //如果第三个参数是false:这个就表示"ajax请求1"不支持异步,也就是说ajax请求1发送之后,会影响其他的ajax请求的发送,只有当我这个请求结束之后,你们其他的ajax请求才能发送。 xhr1.open("请求方式","URL",false) xhr1.send() //假设这个是ajax请求2 //如果第三个参数是true:这个就表示"ajax请求2"支持异步请求,也就是说ajax请求2发送之后,不影响其他的ajax请求的发送。 xhr2.open("请求方式","URL",true) xhr2.send()
- 什么情况下用同步?(大部分情况下我们都是使用ajax异步方式,同步很少用。)
- 举一个列子
- 用户注册
- 用户名需要发送ajax请求进行校验
- 邮箱地址也需要发送ajax请求校验。
- 其他的也可能需要发送ajax请求。。。
- 并且最终注册按钮的时候,也是发送ajax请求进行注册。
- 那么显然,注册的Ajax请求和校验的ajax请求不能异步,必须等待所有的校验ajax请求结束之后,注册的ajax请求才能发。
- 用户注册
- 举一个列子
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>演示ajax同步和异步</title> </head> <body> <script type="text/javascript"> window.onload = function () { document.getElementById("btn1").onclick = function () { var xhr = new XMLHttpRequest(); xhr.onreadystatechange = function () { if (xhr.readyState == 4) { if (xhr.status == 200) { document.getElementById("div1").innerHTML = this.responseText }else { alert(status) } } } // xhr.open("GET","/ajax/ajaxrequest8?"+ new Date().getTime(),true) // 我不支持异步了,我这个请求只要发,你们都得靠边站。都得等着我结束你们才能发请求。 xhr.open("GET","/ajax/ajaxrequest8?"+ new Date().getTime(),false) xhr.send() } document.getElementById("btn2").onclick = function () { var xhr = new XMLHttpRequest(); xhr.onreadystatechange = function () { if (xhr.readyState == 4) { if (xhr.status == 200) { document.getElementById("div2").innerHTML = this.responseText }else{ alert(status) } } } xhr.open("GET","/ajax/ajaxrequest9?"+ 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> </body> </html>
package com.feng; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; /** * @Author feng peng * @Date 2022/10/4 * @Time 17:37 */ @WebServlet("/ajaxrequest8") public class AjaxRequest7Servlet extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { try { Thread.sleep(10*1000); } catch (InterruptedException e) { e.printStackTrace(); } response.setContentType("text/html;charset=UTF-8"); response.getWriter().print("ajax请求1"); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req, resp); } }
package com.feng; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; /** * @Author feng peng * @Date 2022/10/4 * @Time 17:38 */ @WebServlet("/ajaxrequest9") public class AjaxRequest8Servlet 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"); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req, resp); } }
13.AJAX代码封装
- AJAX请求相关的代码都是类似的,有很多重复的代码,这些重复的代码能不能不写,能不能封装一个工具类。要发送ajax请求的话,就直接调用这个工具类中的相关函数即可。
- 接下来,手动封装一个工具类,这个工具类我们可以把它看做是一个JS的库。我们把这个JS库起一个名字,叫做jQuery。(我这里封装的jQuery只是一个前端的库,和后端的java没有关系,只是为了方便web前端代码的编写,提高WEB前端的开发效率)
13.1 js中类的相关回顾
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>回顾javascript中类的定义,对象的创建。属性的访问,方法的访问。</title> </head> <body> <script type="text/javascript"> // 在JS当中怎么定义一个类 function User(usercode,username){ //属性 this.usercode = usercode; this.username = username; // 方法(实例方法,通过对象调用的。) this.doSome = function (){ console.log(username + " doSome....") } // 静态方法(直接用类名调用) User.doOther = function (){ console.log("user doOther....") } } //第二种定义类 /* User = function (usercode,username){ //属性 this.usercode = usercode; this.username = username; // 方法(实例方法,通过对象调用的。) this.doSome = function (){ console.log(username + " doSome....") } // 静态方法(直接用类名调用) User.doOther = function (){ console.log("user doOther....") } }*/ // 创建对象,访问对象的属性,访问对象的方法,访问静态方法 // User(); 直接这样调用,你只是把它当做一个普通的函数去执行,不会创建对象,在堆中没有这个对象。 // new User(); 这样调用的话,其实就是调用该类的构造方法,创建对象,并且在堆中分配空间。 var user = new User("111","zhangsan"); //访问属性 alert(user.usercode+ "," +user.username) //调用方法(实例方法) user.doSome() // 调用静态方法 User.doOther() // 后期如果想给某个类型扩展方法,还可以使用prototype属性 User.prototype.扩展的 = function (){ console.log("打印。。。") } user.扩展的() </script> </body> </html>
13.2 自己封装jQuery
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>手动封装JS库jQuery</title> </head> <body> <script type="text/javascript"> /*封装一个函数,通过这个函数可以获取到html页面中的节点,这个函数我给他起一个名字,叫做: jQuery*/ /*要封装的代码是:根据id来获取元素。document.getElementById("btn")*/ /*设计思路来自于CSS的语法。 #id 可以获取到这个元素*/ function jQuery(selector){ /*selector可能是#id,也可能是其他的选择器,例如类选择器: .class 也可以是任何类型(弱类型)*/ // 根据id获取元素 if (typeof selector == "string") { if(selector.charAt(0) == "#"){ // selector是一个id选择器 /*var domObj = document.getElementById(selector.substring(1))*/ //升级成全局变量 domObj = document.getElementById(selector.substring(1)) //返回的dom对象 // return domObj //返回的jQuery对象 return new jQuery() } } //页面加载完毕之后,注册回调函数。 if (typeof selector == "function") { window.onload = selector } // 定义一个html()函数,代替: domObj.innerHTML = "" this.html = function (htmlStr){ domObj.innerHTML = htmlStr } // 定义一个click()函数,代替: domObj.onclick = function(){} this.click = function (fun){ domObj.onclick = fun } this.val = function (v){ if (v == undefined) { return domObj.value }else{ domObj.value = v } } } $ = jQuery /* window.onload = function (){ /!* document.getElementById("btn").onclick = function (){ document.getElementById("div1").innerHTML = "<font color='red'>用户名不可用!!!</font>" }*!/ /!* jQuery("#btn").onclick = function (){ jQuery("#div1").innerHTML = "<font color='red'>用户名不可用!!!</font>" }*!/ $("#btn").onclick = function (){ $("#div1").innerHTML = "<font color='red'>用户名不可用!!!</font>" } }*/ /* $(function (){} 作用是什么?*/ /* 只要你写上以上的代码,就表示在页面加载完毕之后,执行里面的回调函数。*/ /*$(function (){ $("#btn").onclick = function (){ $("#div1").innerHTML = "<font color='red'>用户名不可用!!!</font>" } })*/ /*$--> jQuery (function)--> 传递了一个函数 */ $(function (){ $("#btn").click(function (){ $("#div1").html("<font color='red'>用户名不可用!!!</font>") // 获取到文本框中的用户名 /* var username = document.getElementById("username").value alert(username)*/ var username = $("#username").val(); alert(username) // 修改文本框的value // document.getElementById("username").value = "呵呵" $("#username").val("呵呵。。。。") }) }) </script> 用户名:<input type="text" id="username"> <button id="btn">显示信息</button> <div id="div1"></div> </body> </html>
把封装的jQuery放入js文件中
function jQuery(selector){ if (typeof selector == "string") { if(selector.charAt(0) == "#"){ domObj = document.getElementById(selector.substring(1)) return new jQuery() } } if (typeof selector == "function") { window.onload = selector } this.html = function (htmlStr){ domObj.innerHTML = htmlStr } this.click = function (fun){ domObj.onclick = fun } this.val = function (v){ if (v == undefined) { return domObj.value }else{ domObj.value = v } } } $ = jQuery
测试封装的jQuery
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>测试我们自己编写的jQuery库(jQuery本质上就是JS的库)</title> </head> <body> <!--使用jQuery库的第一件事,是把jQuery库引进来--> <script type="text/javascript" src="js/jQuery-1.0.0.js"></script> <script type="text/javascript"> $(function (){ $("#btn").click(function (){ // alert("hello") // 获取文本框内容 alert($("#usercode").val()) //修改文本框的value $("#usercode").val("张三") //设置div内容 $("#mydiv").html("我们自己封装的div!!!") }) }) </script> <button id="btn">hello</button> <br> 用户代码:<input type="text" id="usercode"> <br> <div id="mydiv"></div> </body> </html>
13.3 手动开发jQuery,源代码
jQuery.js
function jQuery(selector){ if (typeof selector == "string") { if(selector.charAt(0) == "#"){ domObj = document.getElementById(selector.substring(1)) return new jQuery() } } if (typeof selector == "function") { window.onload = selector } this.html = function (htmlStr){ domObj.innerHTML = htmlStr } this.click = function (fun){ domObj.onclick = fun } this.val = function (v){ if (v == undefined) { return domObj.value }else{ domObj.value = v } } //静态的方法,发送ajax请求 /** * 分析:使用ajax函数发送的ajax请求的时候,需要程序员给我们传过来什么? * 请求的方式(type): GET/POST * 请求的URL(url): url * 请求时提交的数据(data): data * 请求时发送异步请求还是同步请求(async): true表示异步,false表示同步。 * */ jQuery.ajax = function (jsonArgs){ //1. var xhr = new XMLHttpRequest(); //2. xhr.onreadystatechange = function (){ if (xhr.readyState == 4) { if (xhr.status == 200) { // 我们这个工具类在封装的时候,先不考虑那么多,假设服务器返回的都是json格式的字符串。 var jsonObj = JSON.parse(this.responseText) // 调用函数 jsonArgs.success(jsonObj) } } } if(jsonArgs.type.toUpperCase() == "POST"){ //3. xhr.open("POST",jsonArgs.url,jsonArgs.async) //4. xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded") xhr.send(jsonArgs.data) } if (jsonArgs.type.toUpperCase() == "GET") { xhr.open("GET",jsonArgs.url + "?" +jsonArgs.data,jsonArgs.async) xhr.send() } } } $ = jQuery new jQuery()
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>测试我们自己手动开发的jQuery库</title> </head> <body> <!--引入自己写的jQuery库--> <script type="text/javascript" src="js/jQuery-1.0.0.js"></script> <script type="text/javascript"> $(function (){ $("#btn1").click(function (){ //发送ajax请求 $.ajax({ // type : "GET", type : "POST", url : "/ajax/ajaxrequest11", data : "username=" + $("#username").val(), async : true, success : function (json){ $("#div1").html(json.uname) } }) }) }) </script> <button id="btn1">发送ajax请求</button> <br> 用户名: <input type="text" id="username"> <br> <div id="div1"></div> </body> </html>
package com.feng; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.Locale; /** * @Author feng peng * @Date 2022/10/5 * @Time 17:47 */ @WebServlet("/ajaxrequest11") public class AjaxRequest10Servlet extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String username = request.getParameter("username"); response.setContentType("text/html;charset=UTF-8"); //{"username","zhangsan"} response.getWriter().print("{\"uname\":\""+username.toUpperCase()+"\"}"); } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String username = request.getParameter("username"); response.setContentType("text/html;charset=UTF-8"); //{"username","zhangsan"} response.getWriter().print("{\"uname\":\""+username.toLowerCase()+"\"}"); } }
- 使用以上库,怎么用?
<!--引入自己写的jQuery库--> <script type="text/javascript" src="js/jQuery-1.0.0.js"></script> <script type="text/javascript"> $(function (){ $("#btn1").click(function (){ //发送ajax请求 $.ajax({ // type : "GET", type : "POST", url : "/ajax/ajaxrequest11", data : "username=" + $("#username").val(), async : true, success : function (json){ $("#div1").html(json.uname) } }) }) }) </script>
14.AJAX实现省市联动
-
什么是省市联动?
- 在网页上,选择对应的省份之后,动态的关联出该省份对应的市。选择对应的市之后,动态的关联出该市对应的区。(首先要清楚需求)
-
进行数据库表的设计
-
t_area (区域表) id(PK-自增) code name pcode ------------------------------------------------------- 1 001 河北省 null 2 002 河南省 null 3 003 石家庄 001 4 004 邯郸 001 5 005 郑州 002 6 006 洛阳 002 7 007 丛台区 004 将全国所有的省,市,区,县等信息都存储到一张表当中。
采用的存储方式实际上是code pcode形式。
-
自定义的jQuery库:
function jQuery(selector){ if (typeof selector == "string") { if(selector.charAt(0) == "#"){ domObj = document.getElementById(selector.substring(1)) return new jQuery() } } if (typeof selector == "function") { window.onload = selector } this.html = function (htmlStr){ domObj.innerHTML = htmlStr } this.click = function (fun){ domObj.onclick = fun } this.change = function (fun){ domObj.onchange = fun } this.val = function (v){ if (v == undefined) { return domObj.value }else{ domObj.value = v } } //静态的方法,发送ajax请求 /** * 分析:使用ajax函数发送的ajax请求的时候,需要程序员给我们传过来什么? * 请求的方式(type): GET/POST * 请求的URL(url): url * 请求时提交的数据(data): data * 请求时发送异步请求还是同步请求(async): true表示异步,false表示同步。 * */ jQuery.ajax = function (jsonArgs){ //1. var xhr = new XMLHttpRequest(); //2. xhr.onreadystatechange = function (){ if (xhr.readyState == 4) { if (xhr.status == 200) { // 我们这个工具类在封装的时候,先不考虑那么多,假设服务器返回的都是json格式的字符串。 var jsonObj = JSON.parse(this.responseText) // 调用函数 jsonArgs.success(jsonObj) } } } if(jsonArgs.type.toUpperCase() == "POST"){ //3. xhr.open("POST",jsonArgs.url,jsonArgs.async) //4. xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded") xhr.send(jsonArgs.data) } if (jsonArgs.type.toUpperCase() == "GET") { xhr.open("GET",jsonArgs.url + "?" +jsonArgs.data,jsonArgs.async) xhr.send() } } } $ = jQuery new jQuery()
定义类,用于json格式传参:
package com.feng.beans; /** * @Author feng peng * @Date 2022/10/5 * @Time 22:25 */ public class Area { private String code; private String name; public Area() { } public Area(String code, String name) { this.code = code; this.name = name; } public String getCode() { return code; } public void setCode(String code) { this.code = code; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>省市联动</title> </head> <body> <!--引入我们自己编写的jQuery库--> <script type="text/javascript" src="js/jQuery-1.0.0.js"></script> <script type="text/javascript"> $(function (){ //发送ajax请求,获取所有的省份。省份的pcode是null $.ajax({ type: "get", url: "/ajax/listArea", data: "t="+ new Date().getTime(), async: true, success: function (jsonArr){ /*在jQuery库中,把返回的json字符串解析成json对象返回。*/ // [{"code":"001","name":"河北省"},{"code":"002","name":"河南省"}] // 以上格式的json是我们自己设计出来的,希望服务器能够给我们返回这样一个json格式的字符串。 var html = "<option value=''>--请选择省份--</option>"; for (var i = 0; i < jsonArr.length; i++) { var area = jsonArr[i] html += "<option value='"+area.code+"'>" +area.name+ "</option>" } $("#province").html(html) } }) // 只要change发生,就发送ajax请求 /*jQuery库中记得写change事件*/ $("#province").change(function (){ // alert("发送ajax请求") // alert(this) // alert(this.value) //发送ajax请求 $.ajax({ type: "get", url: "/ajax/listArea", data: "t="+ new Date().getTime()+"&pcode=" + this.value, async: true, success: function (jsonArr){ // [{"code":"006","name":"xxx"},{"code":"008","name":"yyyy"}] var html = "<option value=''>--请选择市--</option>"; for (var i = 0; i < jsonArr.length; i++) { var area = jsonArr[i] html += "<option value='"+area.code+"'>" +area.name+ "</option>" } $("#city").html(html) } }) }) }) </script> <select id="province"> <!-- <option value="">请选择省份</option> <option value="001">河北省</option> <option value="002">河南省</option>--> </select> <select id="city"> </select> </body> </html>
package com.feng.servlet; import com.alibaba.fastjson2.JSON; import com.feng.beans.Area; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.sql.*; import java.util.ArrayList; import java.util.List; /** * @Author feng peng * @Date 2022/10/5 * @Time 22:09 */ @WebServlet("/listArea") public class ListAreaServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String pcode = request.getParameter("pcode"); // 连接数据库,获取所有的对应区域。最终响应一个JSON格式的字符串给WEB前端。 Connection conn = null; PreparedStatement ps =null; ResultSet rs = null; List<Area> areaList = new ArrayList<>(); try { // 注册驱动 Class.forName("com.mysql.cj.jdbc.Driver"); // 获取连接 String url = "jdbc:mysql://localhost:3306/mybatis?userUnicode=true&characterEncoding=UTF-8"; String user = "root"; String password = "fp"; conn = DriverManager.getConnection(url,user,password); // 获取预编译数据库操作对象 String sql = ""; if (pcode == null) { sql = "select code,name from t_area where pcode is null"; ps = conn.prepareStatement(sql); }else{ sql = "select code,name from t_area where pcode = ?"; ps = conn.prepareStatement(sql); ps.setString(1,pcode); } // 执行SQL rs = ps.executeQuery(); // 处理结果集 while (rs.next()) { String code = rs.getString("code"); String name = rs.getString("name"); Area a = new Area(code,name); areaList.add(a); } } catch (Exception e) { e.printStackTrace(); }finally { // 释放资源 if (rs != null) { try { rs.close(); } catch (SQLException throwables) { throwables.printStackTrace(); } } if (ps != null) { try { ps.close(); } catch (SQLException throwables) { throwables.printStackTrace(); } } if (conn != null) { try { conn.close(); } catch (SQLException throwables) { throwables.printStackTrace(); } } } response.setContentType("text/html;charset=UTF-8"); // 使用fastjson将java对象转换成json字符串。 String json = JSON.toJSONString(areaList); // 响应JSON。 response.getWriter().print(json); } }
15.AJAX 跨域
15.1 理解
超链接可以跨域吗?
配置两个Tomcat
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>a应用的index页面</title> </head> <body> <!--通过超链接的方式可以跨域吗?--> <a href="http://localhost:8082/b/index.html">b的index页面(跨域访问)</a> </body> </html>
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>b应用的index页面</title> </head> <body> <h1>b应用的index页面</h1> </body> </html>
运行测试
form表单发送请求可以跨域吗?
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>a应用的index页面</title> </head> <body> <!--通过超链接的方式可以跨域吗?--> <a href="http://localhost:8082/b/index.html">b的index页面(跨域访问)</a> <!--form表单发送请求可以跨域吗?--> <form action="http://localhost:8082/b/user/reg" method="post"> 用户名:<input type="text" name="username"><br> 密码:<input type="password" name="password"><br> <input type="submit" value="注册"> </form> </body> </html>
UserRegServlet
package com.feng.servlet; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; @WebServlet("/user/reg") public class UserRegServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // 获取用户名和密码 String username = req.getParameter("username"); String password = req.getParameter("password"); //响应到前端 resp.getWriter().print(username+" : " + password); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req, resp); } }
运行测试
本文作者:千夜ん
本文链接:https://www.cnblogs.com/fengpeng123/p/17951215
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步