一篇文章让你学会如何选择 JS HTTP 请求库

  1. 请求原理

1.1 浏览器

浏览器通过 XMLHttpRequest 对象实现 http 请求。

远古时代 ie6 是借助 ActiveXObject 对象实现 http 请求,目前已无人使用,不考虑兼容。

W3C 标准新提出的 Fecth API,基于 Promise 实现,相对 XMLHttpRequest 对象调用更方便,但旧浏览器不支持 Promise,需要对 Promise 进行 pollyfill。

  • XMLHttpRequest
let xhr = new XMLHttpRequest();
xhr.open('get', url, true);
xhr.send();
xhr.onreadystatechange = function() {
  if(xhr.readyState === 4 && xhr.status === 200 ) {
    let response = JSON.parse(xhr.responseText);
  }
}
  • Fetch
fetch(url)
    .then(response => response.json())
    .then(data => console.log(data))
    .catch(e => console.log("error", e))

1.2 Node.js

Node.js 发布于 2009 年,是一个基于 Chrome V8 引擎的 JavaScript 运行环境,Node.js 的顶层对象是 global,不存在 window 对象,不能通过 XMLHttpRequest 对象实现 http 请求。

Node.js 中通过引入 http/https/http2 模块实现 http 请求,下面为 http 模块实现的例子:

 const http = require('http');
 
const server = http.createServer((req, res) => {
  res.end('hello world');
});
server.on('clientError', (err, socket) => {
  socket.end('HTTP/1.1 400 Bad Request\r\n\r\n');
});
server.listen(8000);

1.3 React Native

React Native 是 Facebook 2015 开源跨平台移动应用开发工具。

React Native 中已经内置了 XMLHttpRequest API,同时提供了和 web 标准一致的Fetch API,所以大部分在 web 端可以使用的网络请求库在 React Native 中也可以使用。

1.4 Weex

Weex 是 阿里 2016 开源跨平台移动应用开发工具。

Weex 通过封装模块来调用原生功能,提供了 stream 模块来实现网络请求。

1.5 小程序

2017 年微信小程序上线,随后各大平台都推出自己的小程序。

小程序由于要对 http 请求做参数校验、兼容各平台(iOS、Android)或版本问题,所以提供了一套属于自己的 API,不提供 window 对象。

下面为微信小程序和支付宝小程序的官网示例:

  • 微信小程序
wx.request({
  url: 'test.php', // 仅为示例,并非真实的接口地址
  data: {
    x: '',
    y: ''
  },
  header: {
    'content-type': 'application/json' // 默认值
  },
  success(res) {
    console.log(res.data)
  }
})
  • 支付宝小程序
my.httpRequest({
  url: 'http://httpbin.org/post',
  method: 'POST',
  data: {
    from: '支付宝',
    production: 'AlipayJSAPI',
  },
  dataType: 'json',
  success: function(res) {
    my.alert({content: 'success'});
  },
  fail: function(res) {
    my.alert({content: 'fail'});
  },
  complete: function(res) {
    my.hideLoading();
    my.alert({content: 'complete'});
  }
});
  1. 请求库

从上文可以看出,平台间的请求方式存在各种差异,请求库就是为解决这种差异。下面为目前较火的请求库。

2.1 $.ajax(支持浏览器)

$.ajax 为 jQuery 对 XMLHttpRequest 对象进行兼容封装。

需要补充的是 React Native 可以使用部分浏览器网络请求库,但是不能使用 jQuery,因为 jQuery 中还使用了很多浏览器中才有而 React Native 中没有的东西。

此外,现在使用框架的项目中我们通常采用其他请求库,或者自己根据项目对 XMLHttpRequest 或 Fetch 进行封装,不会为了网络请求引入 jQuery。

2.2 Request(支持 Node.js)

Request 是对 Node.js 的 http/https 模块封装的 http 库。

var request = require('superagent')
request
  .post('/api/pet')
  .send({ name: 'Manny', species: 'cat' })
  .set('X-API-Key', 'foobar')
  .set('Accept', 'application/json')
  .then(res => {
     alert('yay got ' + JSON.stringify(res.body));
  });

2.4 Axios(支持 React Native,Node,浏览器)

Axios 是一个基于 promise 的 HTTP 请求库,可以用在浏览器和 Node.js 中。浏览器中使用 XMLHttpRequest,Node.js 中使用 http/https 模块。下面为请求示例:

axios.get('/user?ID=12345')
  .then(function (response) {
    console.log(response);
  })
  .catch(function (error) {
    console.log(error);
  });

Vue 2.0 推荐使用 Axios 作为 Vue 的请求库。而且在 SSR 的时候我们在服务端、客户端都需要请求,所以通常会选择 Axios。

2.5 Fly.js(支持 Node.js 、微信小程序 、Weex 、React Native 、Quick App 和浏览器)

Fly.js 是一个基于 promise 的 HTTP 请求库,可以用在Node.js 、微信小程序 、Weex 、React Native 、Quick App 和浏览器中,对上述平台都做了兼容。

fly.get('/user?id=133')
  .then(function (response) {
    console.log(response);
  })
  .catch(function (error) {
    console.log(error);
  });

除了 Fly.js,有些小程序开发框架本身提供网络请求库,对平台做了兼容,比如 Taro.request。

  1. 总结

不同请求库之间的 API、使用都会存在区别。项目开始时,根据需要兼容的平台选择合适的请求库,会大大减少以后代码重构的麻烦。

  • 本文首发于公众号,更多内容欢迎关注我的公众号: 阿夸漫谈

你可能感兴趣的