مقدمة إلىFetch()

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

التوافق مع المتصفح

  • 42
  • 14
  • 39
  • 10.1

المصدر

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