مقدمة إلىFetch()

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

دعم المتصفح

  • Chrome: 42.
  • الحافة: 14.
  • Firefox: 39
  • Safari: الإصدار 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() هو كائن البث، ما يعني أنه بعد التي نطلق عليها الطريقة json()، يتم إرجاع وعود. يحدث البث بشكل غير متزامن.

البيانات الوصفية للردود

أظهر المثال السابق حالة العمود Response وكيفية تحليل الاستجابة كملف 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().

في حال حلّ الوعد، يستدعي النص البرمجي طريقة 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'
})