HTTP数据请求的方式:XMLHttpRequest、ajax、fetch与axios

3,963 阅读7分钟

这是我参与8月更文挑战的第15天,活动详情查看:8月更文挑战

原生 XMLHttpRequest

一、什么是XMLHttpRequest?

XHR英文全名XmlHttpRequest,中文可以解释为可扩展超文本传输请求。Xml可扩展标记语言,Http超文本传输协议,Request请求。XMLHttpRequest对象可以在不向服务器提交整个页面的情况下,实现局部更新网页。当页面全部加载完毕后,客户端通过该对象向服务器请求数据,服务器端接受数据并处理后,向客户端反馈数据。 XMLHttpRequest 对象提供了对 HTTP 协议的完全的访问,包括做出 POST 和 HEAD 请求以及普通的 GET 请求的能力。XMLHttpRequest 可以同步或异步返回 Web 服务器的响应,并且能以文本或者一个 DOM 文档形式返回内容。尽管名为 XMLHttpRequest,它并不限于和 XML 文档一起使用:它可以接收任何形式的文本文档。XMLHttpRequest 对象是名为 AJAX 的 Web 应用程序架构的一项关键功能,XMLHttpRequest 对象用于在后台与服务器交换数据,所有现代的浏览器都支持 XMLHttpRequest 对象。

image.png

二、XMLHttpRequest能干什么?

1、在不重新加载页面的情况下更新网页
2、在页面已加载后从服务器请求数据
3、在页面已加载后从服务器接收数据
4、在后台向服务器发送数据

三、XMLHttpRequest的open()和send()方法

  1. open(method,url,async)方法

    method:请求类型(GET或POST)
    url:文件在服务器上的位置
    async:ture(异步)或 false(同步)

  2. send(string)方法

    string:仅用于POST请求

四、XMLHttpRequest 对象的重要属性:

(1)readyState存有XMLHttpRequest 的状态,0~4。

         0——请求未初始化

         1——服务器连接已经建立

         2——请求已接受

         3——请求处理中

         4——请求已完成,且响应已就绪。

(2)status,HTTP的特定状态码:

  100-199:信息性的标示用户应该采取的其他动作。

  200-299:表示请求成功。

  300-399:用于那些已经移走的文件,常常包括Location报头,指出新的地址。

  400-499:表明客户引发的错误。

  500-599:由服务器引发的错误。

五、原生XMLHttpRequest代码实现

//创建XMLHttpRequest对象
var xhr;
if(window.XMLHttpRequest){
    //IE7+,Firefox,Chrome,Opera,Safari 执行
    xhr = new XMLHttpRequest();
}else{
    // IE6,IE5 执行
    xhr = new ActiveXObject("Microsoft.XMLHTTP");
}

// GET 请求
xhr.open("GET","url",true);
xhr.send();

// POST 请求
xhr.open("POST","url",true);
xhr.send();

//如果需要传参,则需要使用setRequestHeader() 来添加HTTP 头部
xhr.open("POST","url",true);
xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded");
xhr.send("name=tome&age=24");

// 通过 onreadystatechange  事件来监听状态变化,并获取服务器响应
xhr.onreadystatechange = function(){
    //请求成功时
    if(xhr.readyState == 4 && xhr.status == 200){
        alert(xhr.responseText);
    }
}

六、优缺点

优点: 1.不重新加载页面的情况下更新网页 2.在页面已加载后从服务器请求/接收数据 3.在后台向服务器发送数据。 缺点: 1.使用起来也比较繁琐,需要设置很多值。 2.早期的IE浏览器有自己的实现,这样需要写兼容代码。

Ajax

Ajax 的概念

Ajax是对Asynchronous JavaScript + XML(异步JavaScript和XML)的简写,其本身不是一种新技术,而是一个在 2005年被Jesse James Garrett提出的新术语,用来描述一种使用现有技术集合的‘新’方法,包括: HTML 或 XHTML,  CSSJavaScriptDOMXMLXSLT, 以及最重要的 XMLHttpRequest。这一技术能够向服务器请求额外的数据而无需卸载页面,会带来很好的用户体验。Ajax技术的核心是XMLHttpRequest(简称XHR)对象,XHR为向服务器发送请求和解析服务器响应提供了流畅的接口,能够以异步方式从服务器府区区获取更多信息而不必刷新页面。

Ajax 的作用

function success(text) {
    var textarea = document.getElementById('test-response-text');
    textarea.value = text;
}

function fail(code) {
    var textarea = document.getElementById('test-response-text');
    textarea.value = 'Error code: ' + code;
}

//创建XMLHttpRequest对象
var request;
if(window.XMLHttpRequest){
    //IE7+,Firefox,Chrome,Opera,Safari 执行
    request = new XMLHttpRequest();
}else{
    // IE6,IE5 执行
    request = new ActiveXObject("Microsoft.XMLHTTP");
}

request.onreadystatechange = function () { // 状态发生变化时,函数被回调
    if (request.readyState === 4) { // 成功完成
        // 判断响应结果:
        if (request.status === 200) {
            // 成功,通过responseText拿到响应的文本:
            return success(request.responseText);
        } else {
            // 失败,根据响应码判断失败原因:
            return fail(request.status);
        }
    } else {
        // HTTP请求还在继续...
    }
}

// 发送请求:
request.open('GET', '/api/categories');
request.send();

jQuery $.ajax

为了更快捷的操作DOM,并且规避一些浏览器兼容问题,产生了jQuery。【它里面的AJAX请求也兼容了各浏览器,可以有简单易用的方法.get,.post。简单点说,就是 XMLHttpRequest对象的封装。】

优点
1.对原生XHR的封装,做了兼容处理,简化了使用。
2.增加了对JSONP的支持,可以简单处理部分跨域。

缺点
1.如果有多个请求,并且有依赖关系的话,容易形成回调地狱。
2.本身是针对MVC的编程,不符合现在前端MVVM的浪潮。
3.ajax是jQuery中的一个方法。如果只是要使用ajax却要引入整个jQuery非常的不合理。

$.ajax({
    type:'POST,
    url:'http://users/mine',
    data: data,
    dataType:dataType,
    success: function (){},
    error:function (){}
})

Fetch

Fetch 的概念

fetch号称是AJAX的替代品,是在ES6出现的,使用了ES6中的promise对象。Fetch是基于promise设计的。Fetch的代码结构比起ajax简单多了,参数有点像jQuery ajax。但是,一定记住fetch不是ajax的进一步封装,而是原生js,没有使用XMLHttpRequest对象。
fetch的优点:
1.符合关注分离,没有将输入、输出和用事件来跟踪的状态混杂在一个对象里
2.更好更方便的写法,fetch的优势主要优势就是:

Fetch 与 Ajax 对比

// 1.`XMLHttpRequest` 请求数据
var xhr = new XMLHttpRequest();
xhr.open('GET', url);
xhr.responseType = 'json';

xhr.onload = function() {
    console.log(xhr.response);
};

xhr.onerror = function() {
    console.log("Oops, error");
};

xhr.send();

// 2. `fetch`请求数据
fetch(url)
    .then(response => response.json())
    .then(data => console.log(data))
    .catch(e => console.log("Oops, error", e))

两段代码相比之下,fetch更为简洁,而且fetch请求属于promise结构,直接.then()方法处理回调数据,当出错时,会执行catch方法,而且promise避免了回调金字塔的问题

fetch请求的四种方式

get请求

fetch(url)
    .then(response => response.json())
    .then(data => console.log(data))
    .catch(e => console.log("Oops, error", e))

如果需要传递参数,需要拼接在url。后面这里的调用的第一个then函数里面,返回结果是一个可读流形式.如果请求的是json数据,需要调用response.json()(这里的response是传递的参数)将可读流解析为json数据,在下一个then方法中,就可以得到想要的json数据了。同理,如果请求的txt文本数据,则需要调用response.text()来解析...更多调用的解析方法如下:

response.arrayBuffer()
读取 Response对象并且将它设置为已读(因为Responses对象被设置为了 stream 的方式,所以它们只能被读取一次) ,并返回一个被解析为ArrayBuffer格式的promise对象
 
response.blob()
读取 Response对象并且将它设置为已读(因为Responses对象被设置为了 stream 的方式,所以它们只能被读取一次) ,并返回一个被解析为Blob格式的promise对象
 
response.formData()
读取Response对象并且将它设置为已读(因为Responses对象被设置为了 stream 的方式,所以它们只能被读取一次) ,并返回一个被解析为FormData格式的promise对象
 
response.json()
读取 Response对象并且将它设置为已读(因为Responses对象被设置为了 stream 的方式,所以它们只能被读取一次) ,并返回一个被解析为JSON格式的promise对象
 
response.text()
读取 Response对象并且将它设置为已读(因为Responses对象被设置为了 stream 的方式,所以它们只能被读取一次) ,并返回一个被解析为USVString格式的promise对象
post请求
fetch(url,{
    method:'POST',
    headers:{
        'Content-type':'application/json'// 设置请求头数据类型
    },
    body:data
})
.then(res=>res.json())
.then(data=>console.log(data))

method:设置设置请求的方式,默认是get,另外还有PUTDELETE
headers:设置请求头信息,当然,这里面还可以设置别的信息
fetch请求默认是不会携带cookie信息,如果想要携带,需要在手动设置

put请求

fetch(url,{
    method:'PUT',
    headers:{
        'Content-type':'application/json'// 设置请求头数据类型
    },
    body:data
})
.then(res=>res.json())
.then(data=>console.log(data))

delete请求

fetch(url,{
    method:'DELETE',
    headers:{
        'Content-type':'application/json'// 设置请求头数据类型
    },
    body:data
})
.then(res=>res.json())
.then(data=>console.log(data))

axios

Axios是一个基于promise的HTTP库,可以用在浏览器和node.js中。它本质也是对原生XMLHttpRequest的封装,只不过它是Promise的实现版本,符合最新的ES规范 【Vue2.0之后,尤雨溪推荐大家使用axios来请求数据。】

优点
1.从浏览器中创建XMLHttpRequests
2.从node.js创建http请求
3.支持Promise API
4.拦截请求和响应