ajax使用详解及注意事项

ajax简介

Ajax 即“Asynchronous Javascript And XML”(异步 JavaScript 和 XML),是指一种创建交互式网页应用的网页开发技术。
要学一门技术,最基本名字是要读正确的,美式发音音标:[ˈeˌdʒæks] 。对于ajax的这个名字,究其历史原因,当时Ajax技术使用于JavaScript之上,进行的是XML格式数据的传输,通过在后台与服务器进行少量数据交换,Ajax 可以使网页实现异步更新。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新,这样新颖的技术在当时起名:Asynchronous Javascript And XML。但现在XML逐渐被淘汰不在多见了,但ajax强大的异步加载数据功能被保留,所以现在最多做的是利用ajax与json搭配进行前后端的数据交互,理解这一点我们在下面看到带有xml的方法名或者对象名也就不觉得奇怪了。下面我们就直击主题看一下ajax如何在前端实现的。

ajax简单实现

仔细看下面注释,逐句解释一下。

var xhr = new XMLHttpRequest();//名字带有‘xml’的对象
//new 一个请求代理对象。
xhr.open('GET','time.php?id=1');
//建立一个与服务端特定端口的连接(服务端端口一般是80端口),以get方式传输数据
xhr.send(null);
//发送一个请求,请求体内为null(因为是GET请求,这里不放入数据,所以数据会以?id=1的方式传输数据,当为post请求时这里会放入数据。)
xhr.addEventListener('readystatechange',function() {
//注册事件,readystatechange该事件用于监控ajax每个状态的转换,只要转换则就触发该事件。
	if(this.readyState !== 4)return;
	//判断xhr.readyState(ajax状态码)是否为4,不为4则说明没有拿到返回数据
	console.log(this.responseText);
	//返回的数据
});

如何在浏览器查看ajax请求

ajax使用详解及注意事项_第1张图片

ajax各状态码含义及出现的时间

ajax状态码,获取方式

var xhr = new XMLHttpRequest();
xhr.readyState

xhr.readyState在整个ajax操作流程中可以出现5个值,而用readystatechange事件只能检测到4个值

有些文章写到readystatechange事件能检测到三个值,还是有点坑的,其实可以到四个,只需要提前注册一下该事件我们就可以看到。如:

var xhr = new XMLHttpRequest();
xhr.addEventListener('readystatechange',function() {
	console.log(this.readyState);//四个值:1,2,3,4
});
xhr.open('GET','time.php');
xhr.send(null);

ajax使用详解及注意事项_第2张图片
下面我详细介绍一下5个值分别代表什么状态

var xhr = new XMLHttpRequest()
    console.log(xhr.readyState)
    // => 0
    // 初始化 请求代理对象

    xhr.open('GET', 'time.php')
    console.log(xhr.readyState)
    // => 1
    // open 方法已经调用,建立一个与服务端特定端口的连接

    xhr.send()

    xhr.addEventListener('readystatechange', function () {
      switch (this.readyState) {
        case 2:
          // => 2
          // 发送send请求,且已经接受到了响应报文的响应头

          // 可以拿到头
          // console.log(this.getAllResponseHeaders())
          console.log(this.getResponseHeader('server'))
          // 但是还没有拿到体
          console.log(this.responseText)
          break

        case 3:
          // => 3
          // 正在下载响应报文的响应体,有可能响应体为空,也有可能不完整
          // 在这里处理响应体不保险(不可靠)
          console.log(this.responseText)
          break

        case 4:
          // => 4
          // 一切 OK (整个响应报文已经完整下载下来了)
          console.log(this.responseText)
          break
      }
    })

实现一次post请求

上面了解了这么多我们,ajax实现基本流程与get请求已经了解了一个大概,下面我们进行一次post请求,其实与get请求大同小异,唯一不同也许需要设置一下请求头的content-type。

var xhr = (new XMLHttpRequest());
xhr.open('POST','time.php');
xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
//设置请求头的Content-Type为application/x-www-form-urlencoded(简单理解为键值对形式)
//除此外Content-Type还可以设置为:application/json(json格式数据),application/xml(xml格式数据),multipart/form-adta(文件)
xhr.send('key1=value1&key2=value2');//需要发送的数据
xhr.addEventListener('readystatechange',function() {
    if(this.readyState !== 4)return;
    console.log(this.responseText);
});

ajax使用详解及注意事项_第3张图片

XMLHttpRequest实例对象的常用属性

var xhr = (new XMLHttpRequest());

xhr.open('GET','time.php');
//建里连接
xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
//设置头部信息
xhr.send('key1=value1&key2=value2');
//发送请求
xhr.addEventListener('readystatechange',function() {
    if(this.readyState !== 4)return;
    console.log(this.status);//响应状态码,如:200表示成功
    console.log(this.statusText);//响应状态文字描述,如:状态码为200,这里是ok。
    console.log(this.getResponseHeader('Content-Type'));//查看响应报文的Content-Type,数据格式信息
    console.log(this.responseText);//查看响应体信息,即返回的数据。

});

同步与异步

同步是指:发送方发出数据后,等接收方发回响应以后才发下一个数据包的通讯方式。用户填写所有信息后,提交给服务器,等待服务器的回应(检验数据),是一次性的。信息错误又要重新填写!

异步是指:发送方发出数据后,不等接收方发回响应,接着发送下个数据包的通讯方式。当用户填写完一条信息后,该信息会自动向服务器提交,然后服务器响应客户端,在此过程中,用户依然在填写表格的信息,即向服务器请求多次,节省了用户的时间,提高了用户的体验。
原文连接

设置方式:在xhr.open()方法内传入第三个参数,默认为true(异步),传入false则设置为同步方式。

var xhr = new XMLHttpRequest();
xhr.open('GET','time.php',false);

注意一点的是,在使用同步方式时,浏览器会提示:
在这里插入图片描述

也就是说ajax的同步方式是Deprecation的,不赞成的。所以尽量用异步方式。

案例:利用ajax获取系统时间

服务端:


header("Content-Type: application/json");
//设置响应报文Content-Type
$timeDate = array(//需要给前端的数据
	'time' => date('Y-m-d H:i:s',time()),//当前时间
	'history' => '1990-01-01 00:00:00'//一个历史时间
);

if(empty($_GET['key'])){
//没有请求值,返回全部数据
	$json = json_encode($timeDate);
}else{
//有请求值,返回请求值对应数据
	$json = json_encode($timeDate[$_GET['key']]);	
}
echo $json;

前端


<html lang="zh">
<head>
    <meta charset="UTF-8">
    <title>检测事件title>
head>
<body>
    <div>div>
    <script>
    var divEle = document.getElementsByTagName('div')[0];
    var xhr = new XMLHttpRequest();
    xhr.open('GET', 'time.php');
    xhr.send();
    xhr.addEventListener('readystatechange', function() {
        if (this.readyState !== 4) return;
        if (this.status !== 200) {
            console.log("错误" + this.status);
            return
        }
        console.log(this.responseText);
        var timeData = JSON.parse(this.responseText);
        divEle.innerText = timeData.time;
    });
    script>
body>
html>

执行结果:
在这里插入图片描述

补充

1,利用console.time()与console.timeEnd()测试代码执行时间:

	var xhr = new XMLHttpRequest();
    xhr.open('GET', 'time.php',true);
    console.time('GET_t');
    xhr.send();
    console.timeEnd('GET_t');

    var xhr2 = new XMLHttpRequest();
    xhr2.open('GET', 'time.php',false);
    console.time('GET_f');
    xhr2.send();
    console.timeEnd('GET_f');

执行结果:

由此我们也可以看出同步方式与异步方式执行时间上的差别,这个差别在实际传输中还会放大。

在这里插入图片描述
2,用onload事件代替onreadystatechange事件

var xhr3 = new XMLHttpRequest();
    xhr3.open('GET', 'time.php',true);
    xhr3.send();
    xhr3.onload = function () {
        if(this.readyState!==4)return;
        console.log(this.responseText);
    }

3,获取数据前设置数据响应类型

xhr.responseType = 'json';//

设置响应数据的类型为json,设置后获取的数据就是json格式了,无需JSON.parse进行数据转换。
注:但是存在兼容问题,IE10以上版本才可以使用

var xhr4 = new XMLHttpRequest();
    xhr4.open('GET', 'time.php',true);
    xhr4.send();
    xhr4.responseType = 'json';
    xhr4.onload = function () {
        if(this.readyState!==4)return;
        console.log(this);
    }

ajax使用详解及注意事项_第4张图片
4,ajax对IE5,IE6兼容写法

var xhr = window.XMLHttpRequest?new XMLHttpRequest:new ActiveXObject( "Microsoft.XMLHTTP ");

你可能感兴趣的:(JavaScript)