يتيح لك 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()
إلى سوى طلب واحد لتنفيذ العمل نفسه الذي يؤديه مثال fetch()
. لمعالجة الرد، نتحقق أولاً من أنّ حالة الردّ هي
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'
})