前端网络知识整理(1):异步请求的起点ajax

955 阅读5分钟

简介

  ajax是Asynchronous JavaScript+XML的简写,即异步JavaScript+XML。其诞生的目的便是改善用用户的体验

出现原因及背景

  在ajax诞生之前,用户的页面上总是点击,页面会全部刷新,然后等待几分钟甚至更长的时间来重新加载资源,有时网络会超出你想象的慢,然后你的大半个小时就没了,或者在加载页面之初,你就要等待这么长的时间。这种同步的交互方式是十分头疼的,也十分影响效率和心情。为此ajax出现了,它以发送服务器额外的请求而不重新刷新页面,重新加载全部资源,而减少了网络资源加载请求,这使得请求的资源更少,加载的时间更短,用户等待白屏的时间更短,用户体验更好。为此受到了当时人们的青睐。

同步的交互方式会导致请求响应之前,阻塞后面的代码执行,而异步则不会。

具体使用

  在使用ajax时候,我们可以经过如下步骤,发送http请求以及接受返回的响应。

发送请求

  • 初始化XHR对象的实例。所有现代浏览器都支持XMLHttpRequest对象。在不考虑兼容问题时我们可以这么写。
//不加兼容的写法
let xhr = new XMLHttpRequest();

如果加上兼容的写法

let xhr;
if (window.XMLHttpRequest){
    //  IE7+, Firefox, Chrome, Opera, Safari 浏览器执行代码
    xhr=new XMLHttpRequest();
}else{
    // IE6, IE5 浏览器执行代码
    xhr=new ActiveXObject("Microsoft.XMLHTTP");
}

在浏览器中我们可以通过使用XHR(XMLHttpRequest)对象来实现ajax请求

  • 调用open方法为发送请求做准备。open方法有三个参数,即open(method,url,async)。
  • method string类型。请求方法,参数值为GETPOSTPUTDELETE等。
  • url string类型。为资源访问地址,可以是绝对地址,也可以是相对地址。相对地址是相对于代码所在页面的。
  • async boolean类型。同步还是异步的标识,true表示该请求是异步,false表示该请求是同步
xhr.open('GET','http://www.aa.com:80/a/a',true)

url可以不写完全协议、域名、端口。此时该url会被当做相对路径处理。上面的http就是请求协议,www.aa.com是域名,冒号后面的数字就是端口号。如果不写则默认是80端口。

url有同源限制,也就是说将要发起的资源请求原来页面上的请求必须是域名相同、端口相同、协议相同。否则会报错。若这三者有一个不同,请求接收响应失败,这就是常说的跨域问题

  • 调用send方法,请求发送。send方法可以接受一个参数,并将该参数放置到请求的请求体中(body)
  • send(params)。params是个string类型的字符串。如果你不需要传任何参数或者你的请求方法是GET。那么可以写null或者不传。
//GET请求
xhr.send()
xhr.send(null)
//当POST请求时,你可以这么传,params1=1。
//即参数名=值。当需要传多个参数的时候用`&`连接,即参数名=值&参数名=值
xhr.send('params1=1&params2=2')

GET请求的参数直接拼接在url上就可以了。用?隔开资源地址和参数,后面添加参数名=值。

xhr.open('GET','http://www.aa.com:80/a/a?params1=1&params2=2',true)

在经历过上面三个步骤后,我们的请求就已经发出了、

接收响应

  当我们发送完请求后,我们需要服务端给我们一个应答,这个应答就是返回的一些我们所需的数据。那么我们该怎么接收到以及什么时候可以操作数据呢?
  XMLHttpRequest对象提供了事件readystatechange。XMLHttpRequest对象有一个readyState的属性来表示当前当前的请求/响应过程处在哪一个阶段。以下是该属性的状态。

readyState值当前的阶段调用的方法
0未初始化声明实例,还未调用open方法
1已打开已调用open方法 ,未调用send方法
2已发送已调用send方法,尚未收到响应
3接受中已收到部分响应
4完成已收到所有响应,请求响应完成

readyState属性是由XMLHttpRequest对象内部进行维护的,所以我们不需要去操作该属性。每当readyState的值发生改变时,就会触发readystatechange事件。因此我们只需要在监听该事件,并在接收完数据之后操作接收到的数据即可。

xhr.onreadystatechange=function(){
	if(xhr.readyState == 4){
    	//操作数据
    }
}

注意 为了保证浏览器的兼容性 xhr.onreadystatechange事件函数需要在调用open方法之前设置

  虽然上面我们知道怎么接收以及什么时候可以操作数据。但是新的问题来了,我们该从哪里获取数据呢?答案是XMLHttpRequest对象。

  XMLHttpRequest对象为我们提供了四个属性:responseText,responseXML,status,statusText,当收到响应后,XMLHttpRequest对象就会在对于属性上填入对应的值。其意义如下:

  • responseText: 响应体返回的文本
  • responseXML:如果响应内容是XML文档,则包含在此中
  • status:HTTP请求的状态码
  • statusText:HTTP请求状态码的描述

我们知道之前的readyState状态只是表明我们的请求是正常的,但数据是否正常有效则是通过status来进行判断的。在http请求中,状态码在200到300之间表示从服务器得到的响应式有效的,当然还有一种情况下,响应也是有效的,那就是304,表示该资源没有修改过,我们可以从浏览器缓存中取得。所以取得响应数据代码如下。

xhr.onreadystatechange=function(){
	if(xhr.readyState == 4){
    	//操作数据
        if(xhr.status=>200&&xhr.status<300||xhr.status==304){
        	console.log( xhr.responseText)
        }else{
        //响应数据无效,可以做报错处理
        }
    }
}

取消请求

  XMLHttpRequest对象提供了一个取消异步请求的方法,abort。实例调用后就会停止触发该实例相应的事件,并且阻止访问该实例上任何与响应相关的属性。

xhr.abort()

汇总

综合上面的讲述,ajax的使用总共分为以下步骤:

  1. 实例化XMLHttpRequest对象
  2. 设置readyState属性的监听方法onreadystatechange,以便处理响应数据
  3. 调用open方法,确定请求类型、目标资源地址、是否异步。如果是GET请求且需要参数,则将参数拼接在url上
  4. 调用send方法,发送数据。如果是post方法且需要传参,可以在这一步设置 汇总之后代码如下:
let xhr;
if (window.XMLHttpRequest){
    //  IE7+, Firefox, Chrome, Opera, Safari 浏览器执行代码
    xhr=new XMLHttpRequest();
}else{
    // IE6, IE5 浏览器执行代码
    xhr=new ActiveXObject("Microsoft.XMLHTTP");
}
xhr.onreadystatechange=function(){
   if(xhr.readyState == 4){
    	//操作数据
        if(xhr.status=>200&&xhr.status<300||xhr.status==304){
        	console.log( xhr.responseText)
        }else{
        //响应数据无效,可以做报错处理
        }
        xhr=undefined;//用完之后,取消对象引用
    }
}
xhr.open('GET','http://www.aa.com:80/a/a?params1=1&params2=2',true)
xhr.send()

注意:在请响应完成后需要取消对XHR对象的引用,由于内存问题,不建议重用XHR对象实例。

最后

内容难免出错,欢迎指正交流!