文章目录
一、AJAX的功能
Ajax的功能是默认以异步的方式从服务器获取更多的信息。它使得用户无需刷新页面即可从服务器取得数据。
PS:传统的网页(不使用 Ajax)如果需要更新内容,必需重载整个网页面。
同步提交:当用户发送请求时,当前页面不可以使用,服务器响应页面到客户端,响应完成,用户才可以使用页面。
异步提交:当用户发送请求时,当前页面还可以继续使用,当异步请求的数据响应给页面,页面把数据显示出来 。
二、AJAX的核心
Ajax的和核心是:XMLHttpRequest对象(简称XHR)
XHR 为向服务器发送请求和解析服务器响应提供了流畅的接口。能够以异步方式从服务器取得更多信息,意味着用户单击后,可以不必刷新页面也能取得新数据。也就是说,可以使用 XHR 对象取得新数据,然后再通过 DOM 将新数据插入到页面中。另外,虽然名字中包含 XML 的成分,但 Ajax 通信与数据格式无关;这种技术就是无须刷新页面即可从服务器取得数据,但不一定是 XML 数据。
1.XMLHttpRequest对象
同步请求(设置参数为false)
1.创建XHR对象
var xhr = createXHR();
2.XHR的用法
xhr.open("get", "example.php", false);
//open()方法的参数
//参数1:要发送的请求的类型( "get" 、 "post" 等)
//参数2:请求的 URL
//参数3:表示是否异步发送请求的布尔值,此次请求是同步,所以设为false
//上面这行代码会启动一个针对 example.php 的 GET 请求。
//有关这行代码,需要说明两点:一是 URL相对于执行代码的当前页面(当然也可以使用绝对路径);
//二是调用 open() 方法并不会真正发送请求,而只是启动一个请求以备发送。
要发送特定的请求,必须像下面这样调用 send() 方法:
xhr.open("get", "example.txt", false);
xhr.send(null);
//这里的 send() 方法接收一个参数,即要作为请求主体发送的数据。
//如果不需要通过请求主体发送数据,则必须传入 null
//因为这个参数对有些浏览器来说是必需的。
调用 send() 之后,请求就会被分派到服务器。
响应返回
在收到响应后,响应的数据会自动填充 XHR 对象的属性:
responseText :作为响应主体被返回的文本。
responseXML :如果响应的内容类型是 “text/xml” 或 “application/xml” ,这个属性中将保存包含着响应数据的 XML DOM 文档。
status :响应的 HTTP 状态。
statusText :HTTP 状态的说明
在接收到响应后,执行以下步骤:
1、检查 status 属性,以确定响应已经成功返回。(成功时Http状态码200)。
2、获取返回responseText 属性的内容
3、在内容类型正确的情况下, responseXML 也应该能够访问
Tips: 此外,状态代码为 304 表示请求的资源并没有被修改,可以直接使用浏览器中缓存的版本;当然,也意味着响应是有效的。为确保接收到适当的响应,应该像下面这样检查上述这两种状态代码:
if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304){
alert(xhr.responseText);
} else {
alert("Request was unsuccessful: " + xhr.status);
}
根据返回的状态代码,这个例子可能会显示由服务器返回的内容,也可能会显示一条错误消息。我们建议读者要通过检测 status 来决定下一步的操作,不要依赖 statusText ,因为后者在跨浏览器使用时不太可靠。另外,无论内容类型是什么,响应主体的内容都会保存到responseText 属性中;而对于非 XML 数据而言, responseXML 属性的值将为 null 。
//以上是同步请求
异步请求(默认或设置参数为true)
核心: XHR 对象的 readyState 属性,该属性表示请求/响应过程的当前活动阶段(也称为Ajax的状态码)
0 :未初始化。尚未调用 open() 方法。
1 :启动。已经调用 open() 方法,但尚未调用 send() 方法。
2 :发送。已经调用 send() 方法,但尚未接收到响应。
3 :接收。已经接收到部分响应数据。
4 :完成。已经接收到全部响应数据,而且已经可以在客户端使用了。
只要 readyState 属性的值由一个值变成另一个值,都会触发一次 readystatechange 事件。可以利用这个事件来检测每次状态变化后 readyState 的值。通常,我们只对 readyState 值为 4的阶段感兴趣,因为这时所有数据都已经就绪。不过,必须在调用 open() 之前指定 onreadystatechange事件处理程序才能确保跨浏览器兼容性。
//异步
var xhr = createXHR();
//onreadystatechange事件
//专⻔用来监听 ajax 对象的 readyState 值改变的的行为
xhr.onreadystatechange = function(){
//Ajax的状态码配合Http的状态码
//以上两个码都满足的时候,才是本次请求正常完成
if (xhr.readyState == 4){
if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304){
alert(xhr.responseText);
} else {
alert("Request was unsuccessful: " + xhr.status);
}
}
};
xhr.open("get", "example.txt", true);
xhr.send(null);
这个例子在 onreadystatechange 事件处理程序中使用了 xhr 对象,没有使用this 对象,原因是 onreadystatechange 事件处理程序的作用域问题。如果使用this 对象,在有的浏览器中会导致函数执行失败,或者导致错误发生。因此,使用实际的 XHR 对象实例变量是较为可靠的一种方式。
另外,在接收到响应之前还可以调用 abort() 方法来取消异步请求,如下所示:
xhr.abort();
调用这个方法后, XHR 对象会停止触发事件,而且也不再允许访问任何与响应有关的对象属性。
三、实现AJAX基本步骤的简单总结
(此总结没有考虑很多特殊情况,适用大部分非特殊情况)
要完整实现一个AJAX异步调用和局部刷新,通常需要以下几个步骤:
1.创建XMLHttpRequest对象,即创建一个异步调用对象.
var xhr = createXHR();
2.创建一个新的HTTP请求,并指定该HTTP请求的方法、URL及验证信息.
xhr.open("get", "example.txt", true);
3.设置响应HTTP请求状态变化的函数.
if(xmlHttpRequest.readyState == 4) { //设置获取数据的语句}
4.发送HTTP请求.
xhr.send(null);
5.获取异步调用返回的数据. 使用JavaScript和DOM实现局部刷新
四、实现AJAX时携带参数请求
GET方法
若Ajax使用GET的请求方法,那么携带参数直接在 url 后面进行拼接就可以
对 XHR 而言,位于传入 open() 方法的 URL 末尾的查询字符串必须经过正确的编码才行。
使用 GET 请求经常会发生的一个错误,就是查询字符串的格式有问题。
查询字符串中每个参数的名称和值都必须使用encodeURIComponent()
进行编码,然后才能放到 URL 的末尾;而且所有名-值对儿都必须由和号(&)
分隔
如:
xhr.open("get", "example.php?name1=value1&name2=value2",true);
下面这个函数可以辅助向现有 URL 的末尾添加查询字符串参数:
function addURLParam(url, name, value) {
url += (url.indexOf("?") == -1 ? "?" : "&");
url += encodeURIComponent(name) + "=" + encodeURIComponent(value);
return url;
}
这个
addURLParam()
函数接受三个参数:要添加参数的 URL、参数的名称和参数的值。
这个函数 首先检查 URL是否包含问号(以确定是否已经有参数存在)。如果没有,就添加一个问号;否则就添加一个和号。然后,将参数名称和值进行编码,再添加到 URL 的末尾。最后返回添加参数之后的 URL。
下面是使用这个函数来构建请求 URL 的示例。
var url = "example.php";
//添加参数
url = addURLParam(url, "name", "Nicholas");
url = addURLParam(url, "book", "Professional JavaScript");
//初始化请求
xhr.open("get", url, false);
在这里使用
addURLParam()
函数可以确保查询字符串的格式良好,并可靠地用于 XHR 对象。
最后send()
xhr.send();
POST方法
post 请求的参数是携带在请求体中的,所以不需要再 url 后面拼接
POST 请求的主体可以包含非常多的数据,而且格式不限。
步骤:
1.在 open() 方法第一个参数的位置传入 “post” ,就可以初始化一个 POST 请求。
xhr.open("post", "example.php", true);
2.设置好Content-Type 头部信息设置为 application/x-www-form-urlencoded
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
3.向 send() 方法中传入某些数据,发送
xhr.send("name=Bill&age=15")
五、AJAX封装
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
/*
type 代表 请求方式
url 代表 请求url路径
data 代表 发送数据
success 代表 下载数据成功以后执行的函数
error 代表 下载数据失败以后执行的函数
*/
function $ajax({type = "get", url, data, success, error}){
var xhr = null;
try{
xhr = new XMLHttpRequest();
}catch(error){
xhr = new ActiveXObject("Microsoft.XMLHTTP")
}
if(type == "get" && data){
url += "?" + querystring(data);
}
xhr.open(type, url, true);
if(type == "get"){
xhr.send();
}else{
//设置提交数据格式
xhr.setRequestHeader("content-type", "application/x-www-form-urlencoded");
data ? xhr.send(querystring(data)) : xhr.send();
}
xhr.onreadystatechange = function(){
if(xhr.readyState == 4){
if(xhr.status == 200){
if(success){
success(xhr.responseText);
}
}else{
if(error){
error("Error:" + xhr.status);
}
}
}
}
}
function querystring(obj){
var str = '';
for(var attr in obj){
str += attr + "=" + obj[attr] + "&";
}
return str.substring(0, str.length - 1);
}
window.onload = function(){
var aBtns = document.getElementsByTagName("button");
/*
当我们下载完数据以后需要对数据的处理方式不一样
【注】$ajax,我们需要按照传参的顺序,依次传入我们的参数。
*/
aBtns[0].onclick = function(){
$ajax({
url: "code14/1.get.php",
data: {
username: "小明",
age: 18,
password: "123abc"
},
success: function(result){
alert("GET请求到的数据:" + result);
},
error: function(msg){
alert("GET请求数据错误:" + msg);
}
})
}
aBtns[1].onclick = function(){
$ajax({
type: "post",
url: "code14/2.post.php",
data: {
username: "小花",
age: 18,
password: "123abc"
},
success: function(result){
alert("POST请求到的数据:" + result);
},
error: function(msg){
alert("POST请求数据错误:" + msg);
}
})
}
}
</script>
</head>
<body>
<button>GET请求</button>
<button>POST请求</button>
</body>
</html>
总结
XHR对象的方法:
XHR对象的属性:
参考文献:
https://blog.csdn.net/Oriental_/article/details/104863762
https://blog.csdn.net/chaopingyao/article/details/106481895?