يتيح لك fetch()
إجراء طلبات الشبكة بشكل مشابه لـ XMLHttpRequest (XHR). والفرق الرئيسي هو أن واجهة برمجة التطبيقات الجلب تستخدم التعهدات، التي تحتوي على واجهة برمجة تطبيقات أكثر بساطة لمساعدتك في تجنب عمليات معاودة الاتصال المعقدة في واجهة برمجة التطبيقات XMLHttpRequest.
إذا لم يسبق لك استخدام الوعود، يمكنك الاطّلاع على المقالة مقدمة عن وعود JavaScript.
طلب الجلب الأساسي
وفي ما يلي مثال تم تنفيذه باستخدام XMLHttpRequest
ثم باستخدام fetch
. نريد طلب عنوان URL والحصول على استجابة وتحليله كملف JSON.
XMLHttpRequest
يحتاج XMLHttpRequest
إلى مستمعَين للتعامل مع حالات النجاح والخطأ، بالإضافة إلى اتصال بالسمتَين open()
وsend()
.
مثال من مستندات MDN
function reqListener() {
var data = JSON.parse(this.responseText);
console.log(data);
}
function reqError(err) {
console.log('Fetch Error :-S', err);
}
var oReq = new XMLHttpRequest();
oReq.onload = reqListener;
oReq.onerror = reqError;
oReq.open('get', './api/some.json', true);
oReq.send();
استدعاء
يبدو طلب الجلب الذي نقدّمه على النحو التالي:
fetch('./api/some.json')
.then(
function(response) {
if (response.status !== 200) {
console.log('Looks like there was a problem. Status Code: ' +
response.status);
return;
}
// Examine the text in the response
response.json().then(function(data) {
console.log(data);
});
}
)
.catch(function(err) {
console.log('Fetch Error :-S', err);
});
يحتاج الطلب fetch()
إلى مكالمة واحدة فقط لتنفيذ العمل نفسه كمثال XHR. لمعالجة الاستجابة، نتحقق أولاً من أن حالة الاستجابة
200، ثم نحلل الاستجابة بتنسيق JSON. الاستجابة لطلب fetch()
هي كائن Stream، ما يعني أنه بعد أن نستدعي طريقة json()
، يتم عرض "واعد".
يحدث البث بشكل غير متزامن.
البيانات الوصفية للرد
أظهر المثال السابق حالة كائن الاستجابة وكيفية تحليل الاستجابة بتنسيق JSON. إليك كيفية التعامل مع بيانات التعريف الأخرى التي قد ترغب في الوصول إليها، مثل العناوين:
fetch('users.json').then(function(response) {
console.log(response.headers.get('Content-Type'));
console.log(response.headers.get('Date'));
console.log(response.status);
console.log(response.statusText);
console.log(response.type);
console.log(response.url);
});
أنواع الردود
عندما نقدم طلب الاسترجاع، سيتم توفير response.type
للاستجابة "basic
"
أو "cors
" أو
opaque
.
توضح هذه types
مصدر المورد، ويمكنك استخدامها
لتحديد كيفية التعامل مع كائن الاستجابة.
عندما يطلب المتصفّح موردًا على المصدر نفسه، يكون للاستجابة نوع
basic
مع قيود مفروضة على المحتوى الذي يمكنك الاطّلاع عليه من خلال الردّ.
إذا تم تقديم طلب لمورد على مصدر آخر، وعرَض هذا المصدر عناوين COR، يكون النوع هو cors
. cors
تتشابه الردود مع ردود basic
، لكنها تحصر العناوين التي يمكنك الاطّلاع عليها Cache-Control
وContent-Language
وContent-Type
وExpires
وLast-Modified
وPragma
.
تأتي استجابات opaque
من مصدر مختلف لا يعرض عناوين CORS. باستخدام استجابة مبهمة، لن نتمكن من
قراءة البيانات التي يتم عرضها أو عرض حالة الطلب، مما يعني أنه لا يمكنك التحقق
من نجاح الطلب.
يمكنك تحديد وضع لطلب الاسترجاع بحيث يتم حل أنواع طلبات معينة فقط. وفي ما يلي الأوضاع التي يمكنك ضبطها:
- لا تنجح السمة
same-origin
إلا في طلبات الحصول على مواد العرض من المصدر نفسه، وترفض جميع الطلبات الأخرى. - تسمح السمة
cors
بتقديم طلبات مواد العرض على المصدر نفسه والمصادر الأخرى التي تعرض عناوين CORs المناسبة. - تُجري "
cors-with-forced-preflight
" عملية فحص مبدئي قبل تقديم أي طلب. - الغرض من السمة
no-cors
هو إرسال طلبات إلى مصادر أخرى لا تتضمّن رؤوس CORS وتؤدي إلى إرسال استجابةopaque
، ولكن كما ذُكر، لا يمكن إجراء ذلك في النطاق العالمي للنافذة في الوقت الحالي.
لتحديد الوضع، أضِف عنصر خيارات كمَعلمة ثانية في
طلب fetch
وحدِّد الوضع في ذلك العنصر:
fetch('http://some-site.com/cors-enabled/some.json', {mode: 'cors'})
.then(function(response) {
return response.text();
})
.then(function(text) {
console.log('Request successful', text);
})
.catch(function(error) {
log('Request failed', error)
});
سلاسل التعهد
إن إحدى الميزات الرائعة للوعود هي القدرة على ربطها معًا. بالنسبة إلى
fetch()
، يتيح لك هذا الإجراء مشاركة المنطق في جميع طلبات الاسترجاع.
إذا كنت تعمل باستخدام واجهة برمجة تطبيقات JSON، عليك التحقّق من الحالة وتحليل JSON لكل استجابة. يمكنك تبسيط الرمز من خلال تحديد الحالة وتحليل JSON في دوال منفصلة تعرض وعودًا، واستخدام طلب الجلب للتعامل مع البيانات النهائية فقط وحالة الخطأ.
function status(response) {
if (response.status >= 200 && response.status < 300) {
return Promise.resolve(response)
} else {
return Promise.reject(new Error(response.statusText))
}
}
function json(response) {
return response.json()
}
fetch('users.json')
.then(status)
.then(json)
.then(function(data) {
console.log('Request succeeded with JSON response', data);
}).catch(function(error) {
console.log('Request failed', error);
});
يحدد هذا المثال دالة status
التي تتحقّق من response.status
وتعرض إما وعدًا تم حلّه على أنّه Promise.resolve()
، أو تعهد مرفوض على أنّه Promise.reject()
.
هذه هي الطريقة الأولى التي يتم استدعاءها في سلسلة fetch()
.
إذا تم حل Promise، يستدعي النص البرمجي طريقة json()
، والتي تعرض الوعد الثاني من استدعاء response.json()
وتنشئ كائنًا يحتوي على ملف JSON الذي تم تحليله. إذا فشل التحليل، يتم رفض الوعد
وتنفيذ عبارة الصيد.
تتيح لك هذه البنية مشاركة المنطق في جميع طلبات الجلب، ما يسهّل صيانة الرمز وقراءته واختباره.
طلب POST
في بعض الأحيان، يحتاج تطبيق الويب إلى استدعاء واجهة برمجة تطبيقات باستخدام طريقة POST وتضمين بعض
المَعلمات في نص الطلب. لإجراء ذلك، اضبط المعلمتَين method
وbody
في خيارات fetch()
:
fetch(url, {
method: 'post',
headers: {
"Content-type": "application/x-www-form-urlencoded; charset=UTF-8"
},
body: 'foo=bar&lorem=ipsum'
})
.then(json)
.then(function (data) {
console.log('Request succeeded with JSON response', data);
})
.catch(function (error) {
console.log('Request failed', error);
});
إرسال بيانات الاعتماد من خلال طلب جلب
لإجراء طلب استرجاع باستخدام بيانات الاعتماد مثل ملفات تعريف الارتباط، اضبط قيمة credentials
للطلب على "include"
:
fetch(url, {
credentials: 'include'
})