AJAX003——GET请求和POST请求
AJAX GET请求
普通代码
ajax1.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>ajax的get请求</title>
</head>
<body>
<!--用户点击按钮,发送ajax请求。-->
<input type="button" value="helloajax" id="helloBtn">
<!--ajax接收了响应的数据之后,在div中进行渲染。-->
<div id="mydiv">
</div>
<script type="text/javascript">
window.onload = function () {
document.getElementById("helloBtn").onclick = function () {
//发送ajax get请求,一共四步
//1.创建ajax对象
var xhr = new XMLHttpRequest();
//2.注册回调函数
//这个回调函数在XMLHttpRequest对象的readyState属性改变的时候会自动调用。
xhr.onreadystatechange = function () {
//这个函数会被多次调用
//0->1
//1->2
//2->3
//3->4
//XMLHttpRequest对象的readyState属性等于4的时候,表示响应结束
if(this.readyState == 4){
//响应结束之后,会有一个HTTP状态码:200表示成功,404表示资源找不到,500表示服务器内部错误。
// console.log("响应结束。")
if(this.status==404){
alert("资源找不到")
}else if(this.status==500){
alert("服务器内部出现严重错误,请联系管理员。")
}else if(this.status==200){
// alert("请求成功")
//通过XMLHttpRequest对象的responseText属性可以获得服务器的响应数据。
// alert(this.responseText);
//把获取到的信息放到div图层当中。
document.getElementById("mydiv").innerHTML = this.responseText;
}
}
}
//3.开启通道(open只是打开通道,和服务器建立连接,并没有发送请求。)
xhr.open("get","/ajax001/ajaxservlet001",true);
//4.发送请求
xhr.send();
}
}
</script>
</body>
</html>
ajaxservlet001.java
package com.zwm.ajax.web;
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("/ajaxservlet001")
public class ajaxservlet001 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//服务器的代码和原来的一样。
//只是out响应的时候,浏览器客户端的XMLHttpRequest对象会接受到响应的信息。
PrintWriter out = response.getWriter();
out.print("hello,AJAX.");
}
}
提交数据代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<input type="button" value="提交用户名和密码" id="btn">
<script type="text/javascript">
window.onload = function () {
document.getElementById("btn").onclick = function () {
var xmlHttpRequest = new XMLHttpRequest();
xmlHttpRequest.open("GET","/ajax001/ajaxservlet005?username=zwm&userage=23",true);
xmlHttpRequest.send();
xmlHttpRequest.onreadystatechange = function () {
if (xmlHttpRequest.readyState === 4) {
if (xmlHttpRequest.status === 200) {
alert(xmlHttpRequest.responseText)
}
}
}
}
}
</script>
</body>
</html>
package com.zwm.ajax.web;
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("/ajaxservlet005")
public class ajaxservlet005 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String username = request.getParameter("username");
String userage = request.getParameter("userage");
response.setContentType("text/xml;charset=utf-8");
PrintWriter out = response.getWriter();
out.print("姓名:"+username+"年龄:"+userage);
}
}
GET请求的缓存问题
- 对于低版本的IE浏览器来说,AJAX的get请求可能会走缓存。存在缓存问题。对于现代的浏览器来说,大部分浏览器都已经不存在AJAX get缓存问题了。
- 什么是AJAX GET请求缓存问题呢?
- 在HTTP协议中是这样规定get请求的:get请求会被缓存起来。
- 发送AJAX GET请求时,在同一个浏览器上,前后发送的AJAX请求路径一样的话,对于低版本的IE来说,第二次的AJAX GET请求会走缓存,不走服务器。
- POST请求在HTTP协议中规定的是:POST请求不会被浏览器缓存。
- GET请求缓存的优缺点:
- 优点:直接从浏览器缓存中获取资源,不需要从服务器上重新加载资源,速度较快,用户体验好。
- 缺点:无法实时获取最新的服务器资源。
- 浏览器什么时候会走缓存?
- 第一:是一个GET请求
- 第二:请求路径已经被浏览器缓存过了。第二次发送请求的时候,这个路径没有变化,会走浏览器缓存。
- 如果是低版本的IE浏览器,怎么解决AJAX GET请求的缓存问题呢?
- 可以在请求路径url后面添加一个时间戳,这个时间戳是随时变化的。所以每一次发送的请求路径都是不一样的,这样就不会走浏览器的缓存问题了。
- 可以采用时间戳:“url?t=” + new Date().getTime()
- 或者可以通过随机数:“url?t=” + Math.random()
- 也可以随机数+时间戳…
AJAX POST请求
-
AJAX POST请求和GET请求的代码区别在哪里?就是前端代码有区别。后端代码没有区别。
//这行代码用于设置请求头的 Content-Type,指定请求的数据类型为表单形式(application/x-www-form-urlencoded)。 //这行代码应该放在 open() 方法之后、send() 方法之前。模拟form表单提交数据。 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>用户名验证</title> </head> <body> 用户名:<input type="text" id="text-username"> <span id="span-response"></span> <script type="text/javascript"> window.onload = function () { document.getElementById("text-username").onblur = function () { var xmlHttpRequest = new XMLHttpRequest(); xmlHttpRequest.onreadystatechange = function () { if(xmlHttpRequest.readyState == 4){ if(xmlHttpRequest.status == 200){ document.getElementById("span-response").innerHTML = xmlHttpRequest.response; }else{ alert(xmlHttpRequest.status) } } } xmlHttpRequest.open("POST","/ajax001/ajaxservlet006",true); //这行代码用于设置请求头的 Content-Type,指定请求的数据类型为表单形式(application/x-www-form-urlencoded)。 //这行代码应该放在 open() 方法之后、send() 方法之前。 xmlHttpRequest.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); var username = document.getElementById("text-username").value; xmlHttpRequest.send("username="+username); } } </script> </body> </html>
package com.zwm.ajax.web;
import com.zwm.ajax.utils.DBUtil;
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.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
@WebServlet("/ajaxservlet006")
public class ajaxservlet006 extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/xml;charset=utf-8");
PrintWriter out = response.getWriter();
String username = request.getParameter("username");
Connection connection = null;
PreparedStatement preparedStatement = null;
ResultSet resultSet = null;
try {
connection = DBUtil.getConnection();
String sql = "select * from t_user where username = ?";
preparedStatement = connection.prepareStatement(sql);
preparedStatement.setString(1, username);
resultSet = preparedStatement.executeQuery();
if (resultSet.next()) {
out.write("<font color='red'>用户名已存在</font>");
}else {
out.write("<font color='green'>用户名可用</font>");
}
} catch (Exception e) {
e.printStackTrace();
}finally {
DBUtil.close(connection,preparedStatement,resultSet);
}
}
}
package com.zwm.ajax.utils;
import java.sql.*;
import java.util.ResourceBundle;
/**
* @author 猪无名
* @date 2023/8/14 12 26
* discription:JDBC工具类
* @version 1.0
* @since 1.0
*/
public class DBUtil {
private static final ResourceBundle bundle = ResourceBundle.getBundle("resources/jdbc");
private static String driver = bundle.getString("driver");
private static String url = bundle.getString("url");
private static String user = bundle.getString("user");
private static String password = bundle.getString("password");
//不让创建对象,因为工具类中的方法都是静态的,不需要创建对象。
//为了防止创建对象,将构造方法私有化。
private DBUtil(){}
//类加载时,注册驱动。
static {
try {
Class.forName(driver);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
private static ThreadLocal<Connection> threadLocal = new ThreadLocal<>();
/**这里没有使用数据库连接池,直接创建连接对象。
* @return 连接对象
* @throws SQLException
*/
public static Connection getConnection() throws SQLException {
Connection connection = threadLocal.get();
if(connection == null){
connection = DriverManager.getConnection(url, user, password);
threadLocal.set(connection);
}
return connection;
}
/**
* 关闭资源
* @param connection 连接对象
* @param statement 执行对象
* @param resultSet 结果集
*/
public static void close(Connection connection, Statement statement, ResultSet resultSet) {
if (resultSet != null) {
try {
resultSet.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (statement != null) {
try {
statement.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (connection != null) {
try {
connection.close();
//Tomcat服务器是支持线程池的,线程池的线程是复用的,所以需要把连接对象从线程池中移除。
threadLocal.remove();
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
}
}
driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/mvc
user=root
password=root
案例二
-
实现一个案例:用户点击按钮之后,发送AJAX请求,显示学生列表。
- 在后端java程序中拼接HTML代码,然后将HTML代码直接响应到浏览器客户端。这种方式不好,不应该在java代码中编写HTML代码,能否在java程序中直接向前端响应数据?可以,可以在后端拼接JSON格式的字符串,或者XML格式的字符串,将这个字符串发送给前端,前端解析即可。
具体代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<input type="button" value="显示学员列表" id="btn">
<table border="1" width="50%">
<thead>
<tr>
<th>序号</th>
<th>姓名</th>
<th>年龄</th>
<th>住址</th>
</tr>
</thead>
<tbody id="stutbody">
</tbody>
</table>
<script type="text/javascript">
window.onload = function () {
document.getElementById("btn").onclick = function () {
var xhr = new XMLHttpRequest();
xhr.open("get", "/ajax001/ajaxservlet007", true);
xhr.send();
xhr.onreadystatechange = function () {
if(xhr.readyState == 4){
if(xhr.status == 200){
document.getElementById("stutbody").innerHTML = xhr.responseText;
}else {
alert(xhr.status);
}
}
}
}
}
</script>
</body>
</html>
package com.zwm.ajax.web;
import com.zwm.ajax.utils.DBUtil;
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.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
@WebServlet("/ajaxservlet007")
public class ajaxservlet007 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/xml;charset=utf-8");
PrintWriter out = response.getWriter();
Connection connection = null;
PreparedStatement preparedStatement = null;
ResultSet resultSet = null;
try {
connection = DBUtil.getConnection();
String sql = "select * from stu";
preparedStatement = connection.prepareStatement(sql);
resultSet = preparedStatement.executeQuery();
String text = "";
while (resultSet.next()){
int id = resultSet.getInt("id");
String name = resultSet.getString("username");
int age = resultSet.getInt("age");
String address = resultSet.getString("address");
text += "<tr><td>"+id+"</td><td>"+name+"</td><td>"+age+"</td><td>"+address+"</td></tr>";
}
out.print(text);
} catch (Exception e) {
e.printStackTrace();
}finally {
DBUtil.close(connection,preparedStatement,resultSet);
}
}
}
存在的缺点:
在后端进行前端代码的拼接,这样很不好维护,是否可以只返回数据,让前端处理格式?
可以 ,需要借助JSON或者XML。