AJAX、$.ajax、axios、fetch、superagent

1,311 阅读2分钟

原生AJAX

// 1. 创建连接
var xhr = null;
xhr = new XMLHttpRequest()
// 2. 连接服务器
xhr.open('get', url, true)
// 3. 发送请求
xhr.send(null);
// 4. 接受请求
xhr.onreadystatechange = function(){
    if(xhr.readyState == 4){
        if(xhr.status == 200){
            success(xhr.responseText);
        } else { // fail
            fail && fail(xhr.status);
        }
    }
}
  • 优点:

    通过异步模式,提升了用户体验. 优化了浏览器和服务器之间的传输,减少不必要的数据往返,减少了带宽占用.

    Ajax在客户端运行,承担了一部分本来由服务器承担的工作,减少了大用户量下的服务器负载。

    Ajax可以实现动态不刷新(局部刷新)

  • 缺点:

    安全问题 AJAX暴露了与服务器交互的细节。

    对搜索引擎的支持比较弱。

    不容易调试。

$.ajax

jQuery对Ajax的封装

$.ajax({
    dataType: 'json', // 设置返回值类型
    contentType: 'application/json', // 设置参数类型
    headers: {'Content-Type','application/json'},// 设置请求头
    xhrFields: { withCredentials: true }, // 跨域携带cookie
    data: JSON.stringify({a: [{b:1, a:1}]}), // 传递参数
    error:function(xhr,status){  // 错误处理
       console.log(xhr,status);
    },
    success: function (data,status) {  // 获取结果
       console.log(data,status);
    }
})

$.ajax只接收一个参数,这个参数接收一系列配置

Axios

详细可参考:www.jianshu.com/p/7a9fbcbb1…

axios基于Promise对原生的XHR进行了非常全面的封装,使用方式也非常的优雅。另外,axios同样提供了在node环境下的支持,可谓是网络请求的首选方案。支持所有现代浏览器,甚至包括 IE8+!

axios.post('/user', {
    firstName: 'Fred',
    lastName: 'Flintstone'
  })
  .then(function (response) {
    console.log(response);
  })
  .catch(function (error) {
    console.log(error);
  });
  • 优点

    同时支持 Node.js 和浏览器

    支持 Promise API

    可以配置或取消请求

    可以设置响应超时

    支持防止跨站点请求伪造(XSRF)攻击

    可以拦截未执行的请求或响应

    支持显示上传进度

    广泛用于 React 和 Vue 项目

  • 缺点 用起来比较麻烦

Superagent

改良版 Ajax——与 Node.js HTTP 客户端搭配使用

Superagent 是一个基于 Promise 的轻量级渐进式 AJAX API,非常适合发送 HTTP 请求以及接收服务器响应。

与 Axios 相同,它既适用于 Node,也适用于所有现代浏览器。

用 Superagent 发起 HTTP 请求就像在 request 对象上调用方法一样简单:

var superagent = require('superagent');

superagent.post(`${prefix}/payplatform/pay/pay`).withCredentials().send(params).set({'appType': 5, 'blackbox' : blackbox}).then(response => {
    let body = response.body;
    if (body.errno === 0) {
        return body.data;
    } else {
        return Promise.reject(body);
    }
});
  • 优点

它有一个插件生态,通过构建插件可以实现更多功能

可配置

HTTP 请求发送接口友好

可以为请求链式添加方法

适用于浏览器和 Node

支持显示上传和下载进度

支持分块传输编码

支持旧风格的回调

繁荣的插件生态,支持众多常见功能

  • 缺点

其 API 不符合任何标准

Fetch

Fetch 是浏览器自带的用于发送请求的 API,旨在替代 XMLHttpRequest。

使用fetch,你不需要再额外加载一个外部资源。但它还没有被浏览器完全支持,所以你仍然需要一个polyfill。

const options = {
    method: "POST", // 请求参数
    headers: { "Content-Type": "application/json"}, // 设置请求头
    body: JSON.stringify({name:'123'}), // 请求参数
    credentials: "same-origin", // cookie设置
    mode: "cors", // 跨域
}
fetch('http://www.xxx.com',options).then(function(response) {
    return response.json();
}).then(function(myJson) {
    console.log(myJson); // 响应数据
}).catch(function(err){
    console.log(err); // 异常处理
})
  • 优点

    灵活易用

    使用 Promise 避免回调地狱

    支持所有现代浏览器

    遵循 request-response 方案

    语法简单清晰

支持 React Native

  • 缺点

    不支持服务器端使用

    缺乏开发库的亮点功能,比如取消请求

    没有内置默认值,如请求模式,请求头,请求凭据。

最后 用promise封装http请求

function getJSON (url) {
    return new Promise( (resolve, reject) => {
        var xhr = new XMLHttpRequest()
        xhr.open('GET', url, true)

        xhr.onreadystatechange = function () {
            if (this.readyState === 4) {
                if (this.status === 200) {
                    resolve(this.responseText, this)
                } else {
                    var resJson = { code: this.status, response: this.response }
                    reject(resJson, this)
                }
            }
        }

        xhr.send()
    })
}

function postJSON(url, data) {
    return new Promise( (resolve, reject) => {
        var xhr = new XMLHttpRequest()
        xhr.open("POST", url, true)
        xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");

        xhr.onreadystatechange = function () {
            if (this.readyState === 4) {
                if (this.status === 200) {
                    resolve(JSON.parse(this.responseText), this)
                } else {
                    var resJson = { code: this.status, response: this.response }
                    reject(resJson, this)
                }
            }
        }

        xhr.send(JSON.stringify(data))
    })
}
getJSON('/api/v1/xxx').then( value => { 
  // dosomething          
}).catch( error => {
  // dosomething         
})