原生Ajax的学习总结

939 阅读6分钟

这是我的第一篇掘金博客,开启掘金写作之路。

引言

经过几天的学习,想把一些对于异步请求的心得体会分享给各位掘友,同时也是检验我的学习成果。
通过阅读这篇文章,大家可以迅速理解什么是Ajax,了解为什么要用Ajax,掌握原生Ajax的使用方法。

WHAT

首先,要解决的是what,即Ajax是个什么东西。

AJAX 即 Asynchronous Javascript And XML(异步的JavaScript和XML),一种异步请求数据的web开发技术,它是一个标准技术,不需要下载任何控件
简单地说,Ajax 发出异步请求,服务器响应一个xml或者文本数据,此过程只会局部刷新,页面无刷新。

在使用Ajax时,通常会用到js,css,BOM,DOM,XMLHttpRequest对象 常见的使用场景有表单的注册或登录验证、搜索下拉框提示。

一个Ajax的示意图(自己做的,有些丑,见谅)

未命名文件.jpg

WHY

其次,我们需要明白为什么要用Ajax这一技术,即WHY。

我们知道传统的web请求过程是 请求->等待->响应->等待。
浏览器发起一个请求,都要等服务器返回响应后,才会执行下一步。而很多时候,由于网络不稳定,加上服务器自身也需要响应的时间,导致浪费大量时间在等待上。
例如:
使用表单注册账户,提交后,浏览器会将整个注册页面抛弃,等待服务器响应一个新的页面,在等待响应的过程中,用户不能够做其他操作,最后服务器会刷新一个新的网页给浏览器。

显而易见,在这样一个使用场景下,用户的体验是非常差的。并且,对于服务器而言,不断地响应网页也是一种巨大的负担。
这个时候Ajax就派上用场了,因为不会打断用户操作,用户的网络体验变得更加顺畅。而且由于Ajax请求获取的是数据而不是HTML文档(网页),这降低了数据传输量,节省了网络带宽,一定程度上降低了服务器的压力。

总之,Ajax是使网页从低端走向高级的利器。

HOW

最后,我们还需要搞明白如何去使用Ajax,即HOW

步骤

  1. 创建异步对象XMLHttpRequest
  2. 定义HTTP请求,并设置相关参数
  3. 注册监听器,定义响应HTTP请求状态变化的函数
  4. 发送HTTP请求

获取内置对象XMLHttpRequest(记得考虑兼容性)

不同浏览器使用的异步调用对象有所不同

早期的浏览器中,比如ie6: Microsoft.XMLHttp
目前的浏览器里面,对象名: XMLHttpRequest

在IE浏览器中创建XMLHttpRequest对象的方式为:
var xmlHttpRequest = new ActiveXObject("Microsoft.XMLHttp");

在Netscape,Firefox等浏览器中创建XMLHttpRequest对象的方式为:
var xmlHttpRequest = new XMLHttpRequest();`

由于无法确定用户使用的是什么浏览器,所以在创建XMLHttpRequest对象时,最好将以上两种方法都加上
如代码所示:

//定义一个函数用于返回XMLHttpRequest对象
function getXHR(){
    var xhr=null;
    if((typeof XMLHttpRequest)!='undefined'){       //XMLHttpRequest是js中的内置对象,直接调用
        xhr=new XMLHttpRequest();
    }else{
        //ie6  通常只有IE浏览器或以IE浏览器为核心的浏览器才能支持Active控件.
        xhr=new ActiveXObject('Microsoft.XMLHttp');
    }
    return xhr;
}

定义请求

创建了XMLHttpRequest对象之后,必须为XMLHttpRequest对象创建HTTP请求,用于说明XMLHttpRequest对象要从哪里获取数据。

使用XMLHttpRequest对象的open()方法可以定义HTTP请求
即XMLHttpRequest.open(method,URL,async,name,password);

其中常用的参数;

  • method:指定HTTP请求的类型;常用的方法为GET和POST
  • url:文件在服务器上的位置,可以是绝对URL,也可以是相对URL
  • async:参数值为布尔类型,指定是否使用异步请求。true表示异步、false表示同步,默认为true。

注册监听器(响应HTTP请求状态变化的函数)

onreadystatechange事件

定义HTTP请求后,就可以将HTTP请求发送给Web服务器了。

发送HTTP请求的目的是为了接收从服务器中返回的数据,而要获得从服务器端返回的数据,就必须要先判断XMLHttpRequest对象的状态。

所以就用到了XMLHttpRequest对象的属性readyState,它用来标识当前XMLHttpRequest对象处于什么状态。

对于readyState而言,有以下几个值

  • 0:xhr对象未初始化,尚未调用open()方法
  • 1:xhr对象开始发送请求,尚未调用send()方法
  • 2:xhr对象请求发送完成,但尚未接收到响应数据
  • 3:xhr对象开始接收响应的数据
  • 4:xhr对象接收响应数据完毕

这就是XMLHttpRequest对象会经历的5种状态
即,创建XMLHttpRequest对象->发送数据->接收数据。

XMLHttpRequest对象完成了以上5个步骤之后,才能接收响应的数据。

通过xhr的两个属性获取响应数据

  • responseText 获得字符串形式的响应数据。
  • responseXML 获得XML 形式的响应数据。

但是,XMLHttpRequest对象的readyState属性值等于4,仅表示异步调用过程完毕。

异步调用过程完毕,并不代表异步调用成功了,还要判断XMLHttpRequest对象的status属性值(表示http状态码),只有该属性值为200,才表示请求得到了正常的响应,没有异常。
在条件为真时,使用JavaScript和DOM实现局部刷新
例如:

   xhr.onreadystatechange=function(){
        //判断xhr对象的readyState属性值是否为4,status属性值是否为200
        if(xhr.readyState==4 && xhr.status==200){
            //获得服务器响应的文本或者xml
            //let xml=xhr.responseXML;
            let txt=xhr.responseText;
            
            //局部更新----网页的内容----->dom+js
            //自定义操作......
    };

亦或

//定义当XMLHttpRequest对象状态改变时调用的函数,函数名后面不要添加小括号
xmlHttpRequest.onreadystatechange = getData;
    function getData(){
        //判断xhr对象的readyState属性值是否为4,status属性值是否为200
        if(xhr.readyState==4 && xhr.status==200){
            //获得服务器响应的文本或者xml
            //let xml=xhr.responseXML;
            let txt=xhr.responseText;
            
            //局部更新----网页的内容----->dom+js
            //自定义操作......
        }
    }

发送HTTP请求

在经过以上几个步骤的设置之后,就可以将HTTP请求发送到Web服务器上去了。

发送HTTP请求使用xhr对象的send()方法
xhr.send(string);

send()方法在POST请求和GET请求下的使用有所区别

POST请求时send()方法会用字符串参数(与在URL中传递参数的格式类似)参数=参数值 多个用 & 拼接
POST请求不用带参数(null)

并且,
POST请求在发送之前需要设置请求头,为固定格式。
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");

只有在使用send()方法之后,XMLHttpRequest对象的readyState属性值才会开始改变,也才会激发readystatechange事件,并调用函数。

GET和POST请求数据区别

  1. 使用GET请求会被缓存;而POST请求反之 ,除非手动设置
  2. 使用GET请求时,参数放在URL上;而POST请求放在send参数中里
  3. GET比POST更不安全,GET参数直接暴露在URL上,POST放在请求体中
  4. GET请求在URL中传送的参数是有长度限制的,而POST没有.即,GET请求发送数据量小,POST请求发送数据量大

END

水平有限,请多多指教。有什么问题,请在评论区留言。如果觉得文章写的还不错,就给个赞呗,您的支持是对我莫大的鼓励!