Ajax(Asynchronous Javascript And Xml)
-
传统请求的缺点:
- 发送一个请求就会前空掉原界面所有的内容
- Ajax实现局部刷新
-
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SSJMyRBF-1689150304234)(C:\Users\26332\AppData\Roaming\Typora\typora-user-images\image-20230709103508924.png)]
-
什么是异步,什么是同步?
- 异步:假设有他t1和t2线程,t1和t2线程并发
- 同步:假设有他t1和t2线程,t2在执行的时候,必须等待t2线程执行到某个位置
- Ajax是异步请求:在同一个浏览器页面,可以发送多个Ajax请求,这些Ajax请求之间不需要等待
XMLHttpRequest对象
链接:https://blog.youkuaiyun.com/jsdoulaoula/article/details/125889583
Ajax GET请求
发送Ajax get请求,前端jsp代码:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Ajax</title>
</head>
<body>
<script type="text/javascript ">
//页面加载完成后调方法
window.οnlοad=function () {
document.getElementById("btn").onclick = function () {
//1.创建XMLHttpRequest对象
var xhr = new XMLHttpRequest();
//第二步:注册回调函数
//这是一个回调函数,这个函数在XMLHttpRequest对象的readyState状态值发生改变时被调用
xhr.onreadystatechange = function () {
//这里回调函数会被调用多次
//0->1被调用一次
//1->2被调用一次
//2->3被调用一次
//3->4被调用一次
// console.log(xhr.readyState);
//当XMLHttpRequest对象的状态是4的时候,表示响应结束
//readyState是XMLHttpRequest 的状态。0:请求未初始化 1:服务器连接已建立 2:请求已收到 3:正在处理请求 4:请求已完成且响应已就绪
if (xhr.readyState == 4) {
//status是浏览器响应的状态码。200:成功 400:找不到资源 500:服务器错误
if (xhr.status == 200) {
//取到要改变的元素
var text= document.getElementById("textid")
//responseText是将servlet的输出打到这里
text.value=xhr.responseText;
}
}
}
//第三步:开启通道(open只是浏览器和服务器建立连接,通道打开,并不会发送请求)
// open(method: string, url: string): void;
// open(method: string, url: string, async: boolean, username?: string | null, password?: string | null): void;
//method:请求方法,url:请求地址,async:是否异步,username,password
xhr.open("GET","/ajax2/ajaxtese",true)
//发送请求
xhr.send();
}
}
</script>
<input type="button" value="点击我" id="btn">
<%-- <span id="textid"></span>--%>
<input type="text" id="textid">
</body>
</html>
前端代码模板:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Ajax</title>
</head>
<body>
<script type="text/javascript ">
//页面加载完成后调方法
window.οnlοad=function () {
//1.创建XMLHttpRequest对象
var xhr = new XMLHttpRequest();
document.getElementById("btn").onclick = function () {
//2.注册回调函数
//这是一个回调函数,这个函数在XMLHttpRequest对象的readyState状态值发生改变时被调用
//在回调函数后设置textChangeFunction方法
xhr.onreadystatechange = textChangeFunction
//3.开启通道(open只是浏览器和服务器建立连接,通道打开,并不会发送请求)
//method:请求方法,url:请求地址,async:是否异步,username,password
xhr.open("GET","/ajax2/ajaxtese",true)
//4.发送请求
xhr.send();
}
//创建textChangeFunction方法
function textChangeFunction(){
//readyState是XMLHttpRequest 的状态。0:请求未初始化 1:服务器连接已建立 2:请求已收到 3:正在处理请求 4:请求已完成且响应已就绪
if (xhr.readyState == 4) {
//status是浏览器响应的状态码。200:成功 400:找不到资源 500:服务器错误
if (xhr.status == 200) {
//取到要改变的元素
var text= document.getElementById("textid")
//responseText是将servlet的输出打到这里
text.value=xhr.responseText;
}
}
}
}
</script>
<input type="button" value="点击我" id="btn">
<%-- <span id="textid"></span>--%>
<input type="text" id="textid">
</body>
</html>
后端Servlet代码:
package servlet;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
@WebServlet("/ajaxtese")
public class ajaxservlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
PrintWriter out = response.getWriter();
out.print("看text里有值了");
}
}
-
怎么Ajax get请求如何提交数据呢?
-
get请求提交数据是在“请求行”上提交,格式是url?属性名=属性值&属性名=属性值…
-
就在第三步的开启通道前获取数据对象,再开启通道是填写的路径将该数据对象按格式绑定上去
-
前端代码:
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Ajax</title> </head> <body> <script type="text/javascript "> //页面加载完成后调方法 window.οnlοad=function () { document.getElementById("btn").onclick = function () { //1.创建XMLHttpRequest对象 var xhr = new XMLHttpRequest(); //第二步:注册回调函数 //这是一个回调函数,这个函数在XMLHttpRequest对象的readyState状态值发生改变时被调用 xhr.onreadystatechange = function () { //这里回调函数会被调用多次 //0->1被调用一次 //1->2被调用一次 //2->3被调用一次 //3->4被调用一次 // console.log(xhr.readyState); //当XMLHttpRequest对象的状态是4的时候,表示响应结束 //readyState是XMLHttpRequest 的状态。0:请求未初始化 1:服务器连接已建立 2:请求已收到 3:正在处理请求 4:请求已完成且响应已就绪 if (xhr.readyState == 4) { //status是浏览器响应的状态码。200:成功 400:找不到资源 500:服务器错误 if (xhr.status == 200) { //取到要改变的元素 document.getElementById("spanid").innerHTML=xhr.responseText; //responseText是将servlet的输出打到这里 } } } //第三步:开启通道(open只是浏览器和服务器建立连接,通道打开,并不会发送请求) // open(method: string, url: string): void; // open(method: string, url: string, async: boolean, username?: string | null, password?: string | null): void; //method:请求方法,url:请求地址,async:是否异步,username,password var username = document.getElementById("username").value; var password = document.getElementById("password").value; xhr.open("GET","/ajax2/ajaxtese?username="+username+"&password="+password,true) //发送请求 xhr.send(); } } </script> <input type="text" id="username"><br> <input type="password" id="password"><br> <input type="button" value="登录" id="btn"><br> <span id="spanid"></span><br> </body> </html>
后端代码:
package servlet; import jakarta.servlet.ServletException; import jakarta.servlet.annotation.WebServlet; import jakarta.servlet.http.HttpServlet; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.PrintWriter; @WebServlet("/ajaxtese") public class ajaxservlet extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { PrintWriter out = response.getWriter(); String username = request.getParameter("username"); String password = request.getParameter("password"); out.print("账号:"+username+",密码:"+password+"<br>登陆成功"); } }
-
Ajax GET请求的缓存问题
-
对于低版本的IE浏览器,Ajax的get请求可能会走缓存,存在缓存问题
-
对于现在的浏览器来说,大部分浏览器都不存在该问题
-
什么是Ajax get请求的缓存问题呢?
- 在HTTP协议中是这样规定get请求的:get请求会被缓存起来
- 在HTTP协议中是这样规定post请求的:post请求会被缓存起来
-
GET请求缓存的优缺点:
- 直接从浏览器缓存中获取资源,不需要从服务器上重新加载资源,速度较快,用户体验好。
- 缺点:无法实时获取到服务器的资源
-
什么时候会走缓存?
- 第一:是一个GET请求
- 第二:请求路径已经被浏览器缓存过了,第二人发送路径和缓存一模一样
-
如果是低版本的IE浏览器,怎么解决Ajax GET请求的缓存问题呢?
-
在url加一个时间戳,这样每次请求的url都不一样
-
usr?time=new Date().getTime()
-
Ajax POST请求
-
要注意:若想使用POST请求提交form表单数据,则需要注意两点(与GET请求不同点)
-
1.要在打开通道前设置请求头内容类型
xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
-
2.要将绑定的数据放到发送请求处
//放到send()这个函数的小括号当中的数据,会自动在前驱图当中提交数据 var username=document.getElementById("usernameid").value; var password=document.getElementById("passwordid").value; xhr.send("username="+username+"&password="+password);
-
-
全部代码:(后端Java代码不变)
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>发送Ajax POST请求</title> </head> <body> <script type="text/javascript"> window.οnlοad=function (){ document.getElementById("btnid").οnclick=function (){ //创建XMLHttpRequest对象 var xhr = new XMLHttpRequest(); //注册回调函数 xhr.onreadystatechange=function (){ if (xhr.readyState==4){ if (xhr.status==200){ document.getElementById("spanid").innerHTML=xhr.responseText; } } } //开启通道 xhr.open("POST","/ajax/ajaxtext",true); //发送请求 //怎么模拟Ajax提交form表单呢?设置请求头内容类型,必须在open之后 xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded"); //放到sen()这个函数的小括号当中的数据,会自动在前驱图当中提交数据 var username=document.getElementById("usernameid").value; var password=document.getElementById("passwordid").value; xhr.send("username="+username+"&password="+password); } } </script> username:<input type="text" id="usernameid"><br> password:<input type="password" id="passwordid"><br> <input type="button" value="登录" id="btnid"><br> <span id="spanid"> </span> </body> </html>
AJAX经典案例-验证用户名是否可用
-
实现一个案例:使用Ajax POST请求实现用户注册的时候,用户名是否可用
-
实现步骤:
- 在前端,用户输入用户名之后,失去焦点事件blur发生,然后发送Ajax POST请求,提交用户名
- 在后端,接收到用户名,连接数据库,根据用户名在表中搜索
- 如果用户名存在
- 后端响应信息:对不起,用户名已存在(在前端页面以红色字体展示)
- 如果用户名不存在
- 后端响应信息:用户名可使用(在前端以绿色字体展示)
-
//前端代码 <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>用户注册</title> </head> <body> <script type="text/javascript" charset="UTF-8"> window.οnlοad=function (){ //将username框失去焦点事件绑定方法 document.getElementById("usernameid").οnblur=function (){ //创建XMLHttpRequest var xhr = new XMLHttpRequest; //注册回调函数 xhr.onreadystatechange=function (){ //如果请求状态结束则进入 if (xhr.readyState==4){ //如果浏览器请求成功 if (xhr.status==200){ document.getElementById("spanid").innerHTML=xhr.responseText; } } } //开启通道 xhr.open("POST","/userOrder/usernameTest",true); //设置请求头内容类型 xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded"); //绑定数据发送到后端 var username = document.getElementById("usernameid").value; xhr.send("username="+username) } } </script> useranme:<input type="text" id="usernameid"><span id="spanid"></span> <br> password:<input type="password" id="passwordid"><br> <input type="submit" value="登录"><br> </body> </html>
//后端代码 import jakarta.servlet.ServletException; import jakarta.servlet.annotation.WebServlet; import jakarta.servlet.http.HttpServlet; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.PrintWriter; import java.sql.*; @WebServlet("/usernameTest") public class testUsername extends HttpServlet { @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { PrintWriter out = response.getWriter(); response.setContentType("text/html"); //获取前端传来的用户名 String username = request.getParameter("username"); Connection conn=null; PreparedStatement ps=null; ResultSet rs=null; //注册驱动 try { Class.forName("com.mysql.cj.jdbc.Driver"); //创建连接 conn= DriverManager.getConnection("jdbc:mysql://localhost:3306/mvc","root","123456"); String sql="select * from user where username=?"; ps=conn.prepareStatement(sql); ps.setString(1,username); rs=ps.executeQuery(); if (rs.next()){ out.print("<font size=\"2px\" color=\"red\">用户名重复</font>"); }else { out.print("<font size=\"2px\" color=\"green\">用户名合法</font>"); } } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (SQLException throwables) { throwables.printStackTrace(); }finally { if (conn!=null){ try { conn.close(); } catch (SQLException throwables) { throwables.printStackTrace(); } } if (ps!=null){ try { ps.close(); } catch (SQLException throwables) { throwables.printStackTrace(); } } if (rs!=null){ try { rs.close(); } catch (SQLException throwables) { throwables.printStackTrace(); } } } } }
-
基于JSON的数据交换
-
在WEB前端中,如何将一个json格式的字符串转换成json对象(外层的双引号和里面的双引号冲突了,所以加个\来进行转译)
-
var jsonStr = "{\"username\" : \"zhangsan\", \"password\" : \"1233344\"}" var jsonObj = JSON.parse(jsonStr) console.log(jsonObj.username) console.log(jsonObj.password)
-
-
在后端拼接JSON格式的字符串,响应给前端的浏览器
-
json.append("["); 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) + "]";
-
-
拼接JSON格式的字符串太痛苦,可以使用阿里巴巴的fastjson组件,它可以将java对象转换成json格式的字符串
-
List<Student> studentList = new ArrayList<>(); while (rs.next()) { // 取出数据 String name = rs.getString("name"); int age = rs.getInt("age"); String addr = rs.getString("addr"); // 将以上数据封装成Student对象 Student s = new Student(name, age, addr); // 将Student对象放到List集合 studentList.add(s); } // 将List集合转换成json字符串 jsonStr = JSON.toJSONString(studentList);
-
注意:使用fastjson需要引入fastjson-1.2.2.jar
-
基于XML的数据交换
-
注意:如果服务器端响应XML的话,响应的内容类型需要写成:
-
response.setContentType("text/xml;charset=UTF-8");
-
-
基于XML的数据交换,前端代码:
-
<!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(students[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.length; j++) { var node = nameOrAge[j] if (node.nodeName == "name") { //console.log("name = " + node.textContent) html += "<td>"+node.textContent+"</td>" } if (node.nodeName == "age") { //console.log("age = " + node.textContent) html += "<td>"+node.textContent+"</td>" } } html += "</tr>" } document.getElementById("stutbody").innerHTML = html }else{ alert(this.status) } } } // 3.开启通道 xhr.open("GET", "/ajax/ajaxrequest6?t=" + new Date().getTime(), 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>
-
AJax乱码问题
Ajax的异步与同步
版权声明:本文为优快云博主「蓦然回首却已人去楼空」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.youkuaiyun.com/jsdoulaoula/article/details/125889583
Ajax代码封装
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.focus=function (fun){
domObj.onfocus=fun
}
this.blur=function (fun){
domObj.onblur=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 or false
* */
JQuery.ajax=function (jsonArgs){
var xhr=new XMLHttpRequest();
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"){
xhr.open("POST",jsonArgs.url,jsonArgs.async);
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;
//这里有个细节,执行这个目的是为了让静态方法ajax生效
new JQuery()
测试前端代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<script type="text/javascript" src="js/JQuery-1.0.0.js"></script>
<script type="text/javascript">
window.onload=function (){
document.getElementById("btn").onclick=function (){
var username=document.getElementById("username").value
$.ajax({
type:"POST",
url:"/ajax/ajaxrequest",
data:"username="+username,
async:true,
//响应回来之后,拿到响应的数据
success:function (json){
document.getElementById("mydiv").innerHTML=json.username
}
})
}
}
</script>
<button id="btn">发送Ajax请求</button><br>
用户名:<input type="text" id="username"><br>
<div id="mydiv"></div>
</body>
</html>
测试后端代码
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/ajaxrequest")
public class servletTest extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
String username = request.getParameter("username");
response.getWriter().print("{\"username\":\""+username+"\"}");
}
}