fetch()
يتيح لك تقديم طلبات إلى الشبكة مشابهة لطلبات XMLHttpRequest (XHR). يتمثل الاختلاف الرئيسي في أن واجهة برمجة تطبيقات الجلب تستخدم Promises، والتي تحتوي على واجهة برمجة تطبيقات أبسط لمساعدتك في تجنب عمليات الاستدعاء المعقدة في واجهة برمجة تطبيقات XMLHttpRequest.
إذا لم يسبق لك استخدام الوعد من قبل، اطّلِع على مقدّمة عن وعد JavaScript.
طلب استرجاع أساسي
في ما يلي مثال تم تنفيذه باستخدام XMLHttpRequest
ثم باستخدام fetch
نريد طلب عنوان URL، والحصول على استجابة، وتحليله كملف JSON.
XMLHttpRequest
يحتاج XMLHttpRequest
إلى مستمعين للتعامل مع حالات النجاح
والخطأ، واتصال بـ open()
وsend()
.
مثال من مستندات MDN
function reqListener () {
const data = JSON.parse(this.responseText);
console.log(data);
}
function reqError (err) {
console.log('Fetch Error :-S', err);
}
const oReq = new XMLHttpRequest();
oReq.onload = reqListener;
oReq.onerror = reqError;
oReq.open('get', './api/some.json', true);
oReq.send();
جلب
يبدو طلب الجلب على النحو التالي:
fetch('./api/some.json')
.then(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(err => {
console.log('Fetch Error :-S', err);
});
يحتاج طلب fetch()
إلى استدعاء واحد فقط لأداء العمل نفسه كمثال XHR. لمعالجة الاستجابة، نتحقّق أولاً من أنّ حالة الاستجابة هي
200، ثمّ نفكّك الاستجابة بتنسيق JSON. الاستجابة لطلب fetch()
هي كائن
Stream، ما يعني أنّه بعد
استدعاء الطريقة json()
، يتم عرض وعد.
يحدث البث بشكل غير متزامن.
البيانات الوصفية للردّ
أظهر المثال السابق حالة الكائن Response وكيفية تحليل الاستجابة بتنسيق JSON. إليك كيفية التعامل مع بيانات التعريف الأخرى التي قد ترغب في الوصول إليها، مثل العناوين:
fetch('users.json').then(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(response => response.text())
.then(text => {
console.log('Request successful', text);
})
.catch(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(data => {
console.log('Request succeeded with JSON response', data);
}).catch(error => {
console.log('Request failed', error);
});
يحدّد هذا المثال دالة status
التي تتحقّق من response.status
وتعرض إما وعدًا تم حلّه على أنّه Promise.resolve()
أو وعد مرفوض على النحو التالي: Promise.reject()
.
هذه هي الطريقة الأولى التي يتم استدعاءها في سلسلة fetch()
.
إذا تم حلّ الوعد، يستدعي النص البرمجي الطريقة 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(data => {
console.log('Request succeeded with JSON response', data);
})
.catch(error => {
console.log('Request failed', error);
});
إرسال بيانات الاعتماد من خلال طلب استرجاع
لتقديم طلب جلب باستخدام بيانات اعتماد مثل ملفات تعريف الارتباط، اضبط قيمة credentials
للطلب على "include"
:
fetch(url, {
credentials: 'include'
})