序章
フロントエンドは急速に発展している分野であり、フロントエンド テクノロジー スタックでは、フロントエンド リクエストが最も一般的な分野です. インターフェイス データをリクエストすることによってのみ、静的なページを動的にすることができます. この記事では、フロントエンド開発のタイムラインを使用して、フロントエンド要求の技術的進化とその長所と短所を 1 つずつ分析します。
1.XMLHttpRequest
XMLHttpRequest は、サーバーとデータを交換するための最も初期のソリューションです. XMLHttpRequest を使用すると、開発者は最終的にページをリロードせずに Web ページを更新でき、ページのロード後にデータの受け入れと送信を要求できます. また、すべてのブラウザーが XMLHttpRequest オブジェクトを取得できます。
var xhr = new XMLHttpRequest(); //获取xhr对象
ただし、XMLHttpRequest は大まかな基になるオブジェクトであり、ブラウザによって作成方法が異なります。互換性のあるメソッドは次のとおりです。
var xhr;
if (window.XMLHttpRequest) { // Mozilla, Safari...
xhr = new XMLHttpRequest();
} else if (window.ActiveXObject) { // IE
try {
xhr = new ActiveXObject('Msxml2.XMLHTTP');
} catch (e) {
try {
xhr = new ActiveXObject('Microsoft.XMLHTTP'); //IE5,6
} catch (e) {}
}
}
XMLHttpRequest を使用して get リクエストを開始します。
//get请求
xhr.open("GET","test1.txt",true);
xhr.send();
完全なポスト リクエスト コードは次のとおりです。
var xhr;
if (window.XMLHttpRequest) { // Mozilla, Safari...
xhr = new XMLHttpRequest();
} else if (window.ActiveXObject) { // IE
try {
xhr = new ActiveXObject('Msxml2.XMLHTTP');
} catch (e) {
try {
xhr = new ActiveXObject('Microsoft.XMLHTTP');
} catch (e) {}
}
}
if (xhr) {
xhr.onreadystatechange = onReadyStateChange;
xhr.open('POST', '/api', true);
// 设置 Content-Type 为 application/x-www-form-urlencoded
// 以表单的形式传递数据
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xhr.send('username=admin&password=root');
}
// onreadystatechange 方法
function onReadyStateChange() {
// 该函数会被调用四次
if (xhr.readyState === 4 &&xhr.status === 200) {
console.log('执行成功');
} else {
console.log('执行出错');
}
}
2.Jquery Ajax
Jqueryといえば、10年以上フロントエンドを独占し、UI層とデータ層のやり取りの問題を完全に解決した時代で、3大フレームワーク(Angular/React/Vue)が登場するまでは)、フロントエンドが MVVM の波に乗りました。Ajax は、開発者が XHR をより便利に使用できるように XHR をカプセル化します。
$.ajax({ //标准写法
type: 'POST',
url: url,
data: data,
dataType: dataType,
success: function () {},
error: function () {}
});
$.get(url,function(){}); //get请求
$.post(url,body,function(){}); //post请求
$.getJSON(url,function(){}); //get请求从服务器加载Json编码
利点: - ネイティブ XHR のカプセル化 - MVC 用のプログラミング - 完全な互換性 - jsonp のサポート
短所: - MVVMに準拠していない - 非同期モデルは現代的ではない、チェーンに対応していない、コードの可読性が悪い - Jquery全体が大きすぎて導入コストが高すぎる
3. フェッチ
Fetch は実は新しい世界であり、デタッチされた XHR は、Ajax よりも使いやすい Promise に基づく完全な非同期処理メカニズムです。
fetch を使用するコードは、次のように xhr よりも整理されます。
fetch(url).then(function(response) {
return response.json();
}).then(function(data) {
console.log(data);
}).catch(function(e) {
console.log("Oops, error");
});
特に矢印関数を使用した後:
fetch(url).then(response => response.json())
.then(data => console.log(data))
.catch(e => console.log("Oops, error", e))
利点: - より低レベルで、豊富な API (リクエスト、レスポンス) を提供します - ES の新しい Promise 設計に基づいた、XHR から分離された単純な構文
上記を見ると、fetch はとても美しいと思うかもしれませんが、fetch 自体は低レベルの API であり、使い慣れた $.ajax や axios などのさまざまなライブラリをカプセル化するのに役立たない運命にあることを理解してください。関数または実装。
したがって、いくつかの欠点があります: - 互換性が比較的低く、低レベルのブラウザーはサポートしていません。フェッチのポリフィルを実装する必要があります。ブラウザがネイティブ fetch をサポートしているかどうかを判断し、サポートしていない場合でも XMLHttpRequest を使用して実装し、Promise と組み合わせてパッケージ化します。一般的なポリフィルには、es6-promise、babel-polyfill、fetch-ie8 などがあります。
- jsonp をサポートしていません。fetch-jsonp を導入できます
//安装
npm install fetch-jsonp --save-dev
//使用
fetchJsonp(url, {
timeout: 3000,
jsonpCallback: 'callback'
}).then(function(response) {
console.log(response.json());
}).catch(function(e) {
console.log(e)
});
- インターセプターがない場合、カプセル化またはフェッチインターセプターの追加レイヤーが必要です
- デフォルトでは、Cookie はありません。構成を追加する必要があります
fetch(url,{
credentials: 'include' //include表示cookie既可同域,也可跨域,‘same-origin’表示只可同域
});
- アボートなし、タイムアウト タイムアウト処理をサポートしない
The Promise.race(iterable) method returns a Promise object. iterable 内の Promise が解決または拒否されている限り、外部 Promise は同じ値で解決または拒否されます。- 進行状況を取得できません
getReader() メソッドは、周期的に読み取ることができる元のバイト ストリームを読み取るために、fetch の Response.body に実装されています。javascriptを参照してください- フェッチの進行状況インジケータ? - スタック オーバーフロー 2016 - ウェブ ストリームの年
4. アクシオス
Axios も比較的新しいネットワーク リクエスト用のクラス ライブラリであり、Yuxi Youda によって推奨され、VUE のネットワーク リクエストの標準構成になり、これも非常に人気があります。それ自体がネイティブ XHR のラッパーです。- ノードのサポート、http リクエストの作成 - Promise API のサポート - クライアントは CSRF を防止します: 各リクエストは Cookie によって取得されたキーを受け取ります - リクエストとレスポンスをインターセプトします - キャンセル リクエスト
互換性に関しては、axios は本質的にネイティブ XHR のカプセル化ですが、ネイティブ ES6 Promise の実装にも依存しており、フェッチと同様にポリフィル互換性が必要です。
インストール:
//npm
npm install axios
//cdn
<script src="https://unpkg.com/axios/dist/axios.min.js"><\/script>
基本的な使い方は以下の通りです。
axios({
method: 'GET',
url: url,
})
.then(res => {console.log(res)})
.catch(err => {console.log(err)})
// get请求
axios.get(url)
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
// post请求
axios.post(‘/user’, {
name: 'Jerry',
lastName: 'Liang'
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
スペシャルシーンの扱い
開発プロセス中に、複数のリクエストのシリアル化と同時実行という厄介なシナリオに遭遇することがよくあります.同時実行の方が解決しやすいです.コールバック地獄はありませんが、コードの可読性は簡単にだらしなくなります.シリアルの問題は.フロントエンドが絶望的です. 最善の方法はバックエンドでマージを行うことです. バックエンドがこの処理を行わない場合, フロントエンドはコールバック地獄に直面しなければなりません.
複数リクエスト連載
// ajax
$.ajax({
url: '',
data: '',
success: function (data) {
$.ajax({
url: '',
data: '',
success: function (data) {
$.ajax({
// 如此一层嵌套一层
})
}
})
}
})
//axios
axios.get(url)
.then(res => {
return axios.get(url,{
{name:result.name}
});
}).then(res => {
//如此一层层嵌套
});
複数のリクエストを並行して
//ajax 通过计数器实现(虽然Jquery支持$.when的方式,但此处不做案例)
var num = 0;
function all(){
num++;
if(n>=3)console.log('三个请求全部完成');
}
$.ajax({
url: '',
data: '',
success: function (data) {
console.log("ajax请求1 完成");
all();
}
})
$.ajax({
url: '',
data: '',
success: function (data) {
console.log("ajax请求2 完成");
all();
}
})
$.ajax({
url: '',
data: '',
success: function (data) {
console.log("ajax请求3 完成");
all();
}
})
//axios
function getInfo() {
return axios.get(url);
}
function getUser() {
return axios.get(url);
}
axios.all([getInfo(), getUser()])
.then(axios.spread(function (info, user) {
// 两个请求现在都执行完成
}));
選び方(個人の理解、参考程度)
- まず第一に、コードがまだ Jquery に基づいているのであれば、間違いなく ajax が最良の選択であることは確かです。
- 任意の MVVM フレームワークを使用している場合は、何も考えずに axios を使用することをお勧めします. 実際のプロジェクトの使用では、fetch にはさまざまなカプセル化と例外処理が必要であり、すぐには使用できないため、axios は $.ajax を直接置き換えることができます.
- fetch を使用したい場合は、それを独自の一連のベスト プラクティスにカプセル化できると思います。
参考:【調べてまとめ】フロントエンドのリクエスト(xhr/ajax/fetch/axios)に関するあれこれ - ほぼ知っている