一篇文章讓你學會如何選擇 JS HTTP 請求庫

以前前端提到網絡請求通常是指瀏覽器,但現在隨着 Node.js、小程序的出現,網絡請求不再侷限於瀏覽器。本文將帶你瞭解不同請求的原理,以及如何爲項目選擇合適的請求庫。

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'});
  }
});

2. 請求庫

從上文可以看出,平臺間的請求方式存在各種差異,請求庫就是爲解決這種差異。下面爲目前較火的請求庫。

2.1 $.ajax(支持瀏覽器)

https://nodei.co/npm/jquery.png?downloads=true&downloadRank=true&stars=true

$.ajax 爲 jQuery 對 XMLHttpRequest 對象進行兼容封裝。

需要補充的是 React Native 可以使用部分瀏覽器網絡請求庫,但是不能使用 jQuery,因爲 jQuery 中還使用了很多瀏覽器中才有而 React Native 中沒有的東西。

此外,現在使用框架的項目中我們通常採用其他請求庫,或者自己根據項目對 XMLHttpRequest 或 Fetch 進行封裝,不會爲了網絡請求引入 jQuery。

2.2 Request(支持 Node.js)

https://nodei.co/npm/request.png?downloads=true&downloadRank=true&stars=true

Request 是對 Node.js 的 http/https 模塊封裝的 http 庫。

var request = require('request');
request('http://www.google.com', function (error, response, body) {
  console.log('error:', error); // Print the error if one occurred
  console.log('statusCode:', response && response.statusCode); // Print the response status code if a response was received
  console.log('body:', body); // Print the HTML for the Google homepage.
});

2.3 SuperAgent(支持 Node.js)

https://nodei.co/npm/superagent.png?downloads=true&downloadRank=true&stars=true

SuperAgent 和 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,瀏覽器)

https://nodei.co/npm/axios.png?downloads=true&downloadRank=true&stars=true

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 和瀏覽器)

https://nodei.co/npm/flyio.png?downloads=true&downloadRank=true&stars=true

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。

總結

不同請求庫之間的 API、使用都會存在區別。項目開始時,根據需要兼容的平臺選擇合適的請求庫,會大大減少以後代碼重構的麻煩。

  • 本文首發於公衆號,更多內容歡迎關注我的公衆號: 阿誇漫談
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章