Ajax异步请求的理解和使用
1. Ajax 异步请求 说明
AJAX, Asynchronous Javascript And XML,异步 JavaScript 和 XML
,一种创建交互式网页应用的网页开发技术。
原理:
通过在后台与服务器进行少量数据交换,AJAX可以是网页实现异步更新。
这意味着可以在不重新加载整个网页的情况下,对网页的部分内容进行更新
。
(普通不适用AJAX的网页如果需要更新则必须刷新整个页面内容)
作用:
- 可以刷新局部页面内容
- 可以发起异步请求
异步&同步请求:
- 同步请求:当页面内容发生改变时,必须全部刷新,且刷新的时候不能发出其他请求。
- 异步请求:可以局部改变网页的内容,当正在发生改变时,其他的模块内容也可以发出请求。
2. Ajax 实现对象:XMLHttpRequest
XMLHttpRequest 异步请求对象提供了对 HTTP 协议的完全的访问,包括做出 POST 和 HEAD 请求以及普通的 GET 请求的能力。
2.1 xhr 建立 Ajax 流程
- new一个xhr对象;
- 调用xhr对象的open方法;
- send一些数据;
- 对服务器的响应过程进行监听,来知道服务器是否正确得做出了响应,接着就可以做一些事情。比如获取服务器响应的内容,在页面上进行呈现。
2.2 xhr 属性、句柄、方法
按照建立 Ajax 流程:
① 创建
new XMLHttpRequest()
创建一个 XMLHttpRequest 对象
② 事件句柄
onreadystatechange
: 用于指定XMLHttpRequest对象状态改变时的事件处理函数
③ 属性
status
/statusText
:以数字/文本形式返回http状态码readyState
: XMLHttpRequest对象的处理状态,响应返回成功的时候得到通知
0 :请求未初始化。open() 还没有调用,xhr 对象已创建或已被 abort() 方法重置
1 :服务器连接已建立。open() 已经调用了,但是 send() 方法未调用。请求还没有被发送
2 :请求已经接收。send() 方法已调用,HTTP 请求已发送到 Web 服务器
3 :请求处理中。所有响应头信息已接收,响应体开始接收单未完成
4 :请求已完成。响应已就绪,HTTP 响应已经完全接收,也就是响应完成了
- 当
status === 200 && readyState === 4
时才去读取响应数据。
responseText
/responsXML
:获得字符串/XML形式的响应数据getAllResponseHeader()
:获取所有的响应报头getResponseHeader()
:查询响应中的某个字段的值
④ 方法
open()
:打开链接。
open(请求方式, 请求路径, flag); // flag==true 异步请求, false 同步请求
setRequestHeader()
:设置请求头。
模拟form表单,专用于POST请求
setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
send()
: 发送数据
GET请求,send 方法不需要携带参数,直接将参数拼接在 open 方法的路径后面
POST 请求,需要 send 方法带参来发送
send(请求参数数据);
3. Ajax 异步 GET/POST 请求
服务器 Servlet 处理请求的资源:
@WebServlet(name = "TestAjaxServlet", urlPatterns = "/ajax")
public class TestAjaxServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ... {
// 获取参数
String username = request.getParameter("username");
String password = request.getParameter("password");
if (username != null && password != null) {
String msg = "账户可用";
boolean flag = true;
Map<String, Object> map = new HashMap<>();
map.put("flag", flag);
map.put("msg", msg);
// 封装 JSON 字符串
ObjectMapper objectMapper = new ObjectMapper();
String resp = objectMapper.writeValueAsString(map);
// 响应到浏览器(浏览器页面 Ajax 会接收处理)
response.setContentType("text/html;charset=utf-8");
response.getWriter().write(resp);
}
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throw ... {
doPost(request, response);
}
}
3.1 Ajax GET 请求
<title>ajax-get请求</title>
<script>
/**
* 1. 创建异步请求对象 XMLHttpRequest
* @returns {XMLHttpRequest}
*/
function createXMLHttpRequest() {
var xmlHttp;
try {
// IE7+, Chrome, Firefox, Opera 8.0+, Safari 主流浏览器
xmlHttp = new XMLHttpRequest();
} catch (e) {
try {
// IE6, IE5 浏览器
xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
try {
// 其他浏览器
xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
} catch (e) {
// Nothing to do.
}
}
}
return xmlHttp;
}
var xhr = createXMLHttpRequest();
// 2. 监听异步请求对象的状态改变 (当异步请求对象状态发生改变就会执行本方法)
xhr.onreadystatechange = function () {
console.log("异步请求对象:状态发生改变,状态 = " + xhr.readyState);
// 判断服务器响应状态码 status && 判断服务器响应完成状态 readyState
if (xhr.status === 200 && xhr.readyState === 4) {
console.log("请求成功,读取响应完成...");
var responseText = xhr.responseText;
// json字符串 >> js对象
var jsObj = eval("(" + responseText + ")");
console.log(jsObj.flag + ":" + jsObj.msg);
}
};
// 3. 打开链接
xhr.open("get", "${pageContext.request.contextPath}/ajax?username=root&password=1234", true);
// 4. 发送数据(GET请求的参数必须拼接在请求链接中)
xhr.send();
</script>
3.2 Ajax POST 请求
<title>ajax-post请求</title>
<script>
// 1.创建异步请求对象
function createXMLHttpRequest() {
var xmlHttp;
try {
// IE7+, Chrome, Firefox, Opera 8.0+, Safari 主流浏览器
xmlHttp = new XMLHttpRequest();
} catch (e) {
try {
// IE6, IE5 浏览器
xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
try {
// 其他浏览器
xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
} catch (e) {
// Nothing to do.
}
}
}
return xmlHttp;
}
var xhr = createXMLHttpRequest();
// 2. 监听异步请求对象的状态改变 (当异步请求对象状态发生改变就会执行本方法)
xhr.onreadystatechange = function () {
console.log("异步请求对象:状态发生改变,状态 = " + xhr.readyState);
// 判断服务器响应状态码 status && 判断服务器响应完成状态 readyState
if (xhr.status === 200 && xhr.readyState === 4) {
console.log("请求成功,读取响应完成...");
var responseText = xhr.responseText;
console.log(responseText);
// json字符串 >> js对象
var jsObj = eval("(" + responseText + ")");
console.log(jsObj.flag);
console.log(jsObj.msg);
}
};
// 3.打开链接
xhr.open("post", "${pageContext.request.contextPath}/ajax", true);
// 4.设置请求头(模拟 form 表单)
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
// 5.发送参数
xhr.send("username=root&password=1234");
</script>
【注意事项】在以下情况中
请使用 POST 请求
:
- 无法使用缓存文件(更新服务器上的文件或数据库)
- 向服务器发送大量数据(POST 没有数据量限制)
- 发送包含未知字符的用户输入时,POST 比 GET 更稳定也更可靠