(详细易懂)一篇文章让你读懂到底什么是Ajax


一、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?

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值