مقدمة إلىFetch()

يتيح لك fetch() تقديم طلبات شبكة مشابهة لـ XMLHttpRequest (XHR). تشير رسالة الأشكال البيانية يتمثل الاختلاف الرئيسي في أن واجهة برمجة تطبيقات الجلب تستخدم Promises، واجهة برمجة تطبيقات أبسط لمساعدتك في تجنب عمليات الاسترداد المعقدة في واجهة برمجة التطبيقات XMLHttpRequest.

دعم المتصفح

  • Chrome: 42.
  • ‫Edge: 14
  • Firefox: 39
  • ‫Safari: 10.1

المصدر

إذا لم يسبق لك استخدام الوعد من قبل، اطّلِع على مقدّمة عن وعد 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'
})