Fetch API

यह कोडलैब, प्रोग्रेसिव वेब ऐप्लिकेशन डेवलप करने से जुड़े ट्रेनिंग कोर्स का हिस्सा है. इसे Google Developers Training टीम ने बनाया है. अगर कोडलैब को क्रम से पूरा किया जाता है, तो आपको इस कोर्स से सबसे ज़्यादा फ़ायदा मिलेगा.

कोर्स के बारे में पूरी जानकारी के लिए, प्रोग्रेसिव वेब ऐप्लिकेशन डेवलप करने के बारे में खास जानकारी देखें.

परिचय

इस लैब में, आपको Fetch API का इस्तेमाल करने के बारे में बताया गया है. यह एपीआई, संसाधनों को फ़ेच करने के लिए एक आसान इंटरफ़ेस है. साथ ही, यह XMLHttpRequest API से बेहतर है.

आपको क्या सीखने को मिलेगा

  • संसाधनों का अनुरोध करने के लिए, Fetch API का इस्तेमाल कैसे करें
  • फ़ेच का इस्तेमाल करके GET, HEAD, और POST अनुरोध कैसे करें
  • कस्टम हेडर पढ़ने और सेट करने का तरीका
  • सीओआरएस के इस्तेमाल और इसकी सीमाओं के बारे में जानकारी

आपको क्या पता होना चाहिए

  • JavaScript और एचटीएमएल की बुनियादी जानकारी
  • ES2015 Promises के कॉन्सेप्ट और बुनियादी सिंटैक्स के बारे में जानकारी होना

आपको इन चीज़ों की ज़रूरत होगी

  • टर्मिनल/शेल ऐक्सेस वाला कंप्यूटर
  • इंटरनेट कनेक्शन
  • ऐसा ब्राउज़र जो Fetch के साथ काम करता हो
  • टेक्स्ट एडिटर
  • Node और npm

ध्यान दें: फ़िलहाल, Fetch API सभी ब्राउज़र में काम नहीं करता. हालांकि, इसके लिए polyfill उपलब्ध है.

github से pwa-training-labs रिपॉज़िटरी को डाउनलोड या क्लोन करें. साथ ही, अगर ज़रूरी हो, तो Node.js का एलटीएस वर्शन इंस्टॉल करें.

अपने कंप्यूटर की कमांड लाइन खोलें. fetch-api-lab/app/ डायरेक्ट्री में जाएं और लोकल डेवलपमेंट सर्वर शुरू करें:

cd fetch-api-lab/app
npm install
node server.js

Ctrl-c की मदद से, सर्वर को किसी भी समय बंद किया जा सकता है.

अपना ब्राउज़र खोलें और localhost:8081/ पर जाएं. आपको अनुरोध करने के लिए बटन वाला एक पेज दिखेगा. हालांकि, ये बटन अभी काम नहीं करेंगे.

ध्यान दें: सभी सर्विस वर्कर का रजिस्ट्रेशन रद्द करें और लोकल होस्ट के लिए सभी सर्विस वर्कर कैश मिटाएं, ताकि वे लैब में कोई रुकावट न डालें. Chrome DevTools में, ऐप्लिकेशन टैब के स्टोरेज मिटाएं सेक्शन में जाकर, साइट का डेटा मिटाएं पर क्लिक करके ऐसा किया जा सकता है.

अपने पसंदीदा टेक्स्ट एडिटर में fetch-api-lab/app/ फ़ोल्डर खोलें. आपको app/ फ़ोल्डर में लैब बनानी होगी.

इस फ़ोल्डर में ये चीज़ें शामिल हैं:

  • echo-servers/ में ऐसी फ़ाइलें होती हैं जिनका इस्तेमाल टेस्ट सर्वर चलाने के लिए किया जाता है
  • examples/ में ऐसे सैंपल संसाधन शामिल होते हैं जिनका इस्तेमाल हम फ़ेच करने से जुड़े एक्सपेरिमेंट में करते हैं
  • js/main.js ऐप्लिकेशन के लिए मुख्य JavaScript है. इसमें आपको अपना पूरा कोड लिखना होगा
  • index.html हमारी सैंपल साइट/ऐप्लिकेशन का मुख्य एचटीएमएल पेज है
  • package-lock.json और package.json, हमारे डेवलपमेंट सर्वर और इको सर्वर की डिपेंडेंसी के लिए कॉन्फ़िगरेशन फ़ाइलें हैं
  • server.js एक नोड डेवलपमेंट सर्वर है

Fetch API का इंटरफ़ेस काफ़ी आसान है. इस सेक्शन में, फ़ेच का इस्तेमाल करके बुनियादी एचटीटीपी अनुरोध लिखने का तरीका बताया गया है.

JSON फ़ाइल फ़ेच करना

js/main.js में, ऐप्लिकेशन के Fetch JSON बटन को fetchJSON फ़ंक्शन से अटैच किया गया है.

examples/animals.json फ़ाइल का अनुरोध करने और जवाब को लॉग करने के लिए, fetchJSON फ़ंक्शन को अपडेट करें:

function fetchJSON() {
  fetch('examples/animals.json')
    .then(logResult)
    .catch(logError);
}

स्क्रिप्ट सेव करें और पेज को रीफ़्रेश करें. JSON फ़ेच करें पर क्लिक करें. कंसोल को फ़ेच रिस्पॉन्स लॉग करना चाहिए.

जानकारी

fetch वाला तरीका, उस संसाधन का पाथ स्वीकार करता है जिसे हमें पैरामीटर के तौर पर वापस पाना है. इस मामले में, यह examples/animals.json है. fetch एक प्रॉमिस दिखाता है, जो Response ऑब्जेक्ट में रिज़ॉल्व होता है. अगर प्रॉमिस पूरा हो जाता है, तो जवाब को logResult फ़ंक्शन को पास कर दिया जाता है. अगर प्रॉमिस अस्वीकार कर दिया जाता है, तो catch फ़ंक्शन काम करना शुरू कर देता है. साथ ही, गड़बड़ी को logError फ़ंक्शन को पास कर दिया जाता है.

रिस्पॉन्स ऑब्जेक्ट, अनुरोध के जवाब को दिखाते हैं. इनमें जवाब का मुख्य हिस्सा होता है. साथ ही, काम की प्रॉपर्टी और तरीके भी होते हैं.

गलत जवाबों की जांच करना

कंसोल में लॉग किए गए जवाब की जांच करें. status, url, और ok प्रॉपर्टी की वैल्यू नोट करें.

fetchJSON में मौजूद examples/animals.json संसाधन को examples/non-existent.json से बदलें. अपडेट किया गया fetchJSON फ़ंक्शन अब ऐसा दिखना चाहिए:

function fetchJSON() {
  fetch('examples/non-existent.json')
    .then(logResult)
    .catch(logError);
}

स्क्रिप्ट सेव करें और पेज को रीफ़्रेश करें. इस संसाधन को फ़ेच करने के लिए, JSON फ़ेच करें पर फिर से क्लिक करें.

देखें कि फ़ेच करने की प्रोसेस पूरी हो गई हो और catch ब्लॉक ट्रिगर न हुआ हो. अब नए जवाब की status, URL, और ok प्रॉपर्टी ढूंढें.

दोनों फ़ाइलों के लिए वैल्यू अलग-अलग होनी चाहिए. क्या आपको पता है कि ऐसा क्यों होना चाहिए? अगर आपको कंसोल में कोई गड़बड़ी मिली है, तो क्या वैल्यू, गड़बड़ी के कॉन्टेक्स्ट से मेल खाती हैं?

जानकारी

जवाब नहीं मिलने पर, catch ब्लॉक क्यों चालू नहीं हुआ? यह फ़ेच और प्रॉमिस के लिए ज़रूरी जानकारी है—खराब जवाब (जैसे कि 404) अब भी हल हो जाते हैं! फ़ेच प्रॉमिस सिर्फ़ तब अस्वीकार होता है, जब अनुरोध पूरा नहीं किया जा सकता. इसलिए, आपको हमेशा जवाब की वैधता की जांच करनी चाहिए. हम अगले सेक्शन में जवाबों की पुष्टि करेंगे.

अधिक जानकारी के लिए

जवाब की पुष्टि करना

जवाबों की पुष्टि करने के लिए, हमें अपने कोड को अपडेट करना होगा.

main.js में, जवाबों की पुष्टि करने के लिए कोई फ़ंक्शन जोड़ें:

function validateResponse(response) {
  if (!response.ok) {
    throw Error(response.statusText);
  }
  return response;
}

इसके बाद, fetchJSON की जगह यह कोड डालें:

function fetchJSON() {
  fetch('examples/non-existent.json')
    .then(validateResponse)
    .then(logResult)
    .catch(logError);
}

स्क्रिप्ट सेव करें और पेज को रीफ़्रेश करें. JSON फ़ेच करें पर क्लिक करें. कंसोल देखें. अब examples/non-existent.json के जवाब से, catch ब्लॉक ट्रिगर होना चाहिए.

fetchJSON फ़ंक्शन में मौजूद examples/non-existent.json को ओरिजनल examples/animals.json से बदलें. अपडेट किया गया फ़ंक्शन अब इस तरह दिखेगा:

function fetchJSON() {
  fetch('examples/animals.json')
    .then(validateResponse)
    .then(logResult)
    .catch(logError);
}

स्क्रिप्ट सेव करें और पेज को रीफ़्रेश करें. JSON फ़ेच करें पर क्लिक करें. आपको दिखेगा कि जवाब को पहले की तरह ही लॉग किया जा रहा है.

जानकारी

हमने validateResponse की जांच करने की सुविधा जोड़ दी है. अब खराब जवाब (जैसे कि 404) मिलने पर गड़बड़ी का मैसेज दिखता है और catch की सुविधा चालू हो जाती है. इससे हमें जवाब न मिलने की समस्या को ठीक करने में मदद मिलती है. साथ ही, फ़ेच चेन में अनचाहे जवाबों को आगे बढ़ने से रोका जा सकता है.

जवाब पढ़ना

फ़ेच किए गए जवाबों को ReadableStreams (streams spec) के तौर पर दिखाया जाता है. जवाब के मुख्य हिस्से को ऐक्सेस करने के लिए, इन्हें पढ़ना ज़रूरी है. जवाब देने वाले ऑब्जेक्ट में, ऐसा करने के लिए तरीके होते हैं.

main.js में, readResponseAsJSON फ़ंक्शन को इस कोड के साथ जोड़ें:

function readResponseAsJSON(response) {
  return response.json();
}

इसके बाद, fetchJSON फ़ंक्शन को इस कोड से बदलें:

function fetchJSON() {
  fetch('examples/animals.json') // 1
  .then(validateResponse) // 2
  .then(readResponseAsJSON) // 3
  .then(logResult) // 4
  .catch(logError);
}

स्क्रिप्ट सेव करें और पेज को रीफ़्रेश करें. JSON फ़ेच करें पर क्लिक करें. कंसोल में जाकर देखें कि examples/animals.json से मिले JSON को लॉग किया जा रहा है, न कि रिस्पॉन्स ऑब्जेक्ट को.

जानकारी

आइए, देखते हैं कि क्या हो रहा है.

पहला चरण. किसी संसाधन को फ़ेच किया जाता है, examples/animals.json. फ़ेच, एक प्रॉमिस दिखाता है. यह प्रॉमिस, Response ऑब्जेक्ट में बदल जाता है. जब प्रॉमिस रिज़ॉल्व हो जाता है, तो रिस्पॉन्स ऑब्जेक्ट को validateResponse में पास किया जाता है.

दूसरा चरण. validateResponse यह देखता है कि जवाब मान्य है या नहीं (क्या यह 200 है?). अगर ऐसा नहीं होता है, तो गड़बड़ी का मैसेज दिखता है. साथ ही, बाकी then ब्लॉक को छोड़कर, catch ब्लॉक ट्रिगर हो जाता है. यह खास तौर पर ज़रूरी है. इस जांच के बिना, खराब जवाबों को चेन से पास कर दिया जाता है. इससे बाद में ऐसा कोड काम नहीं कर सकता जो मान्य जवाब पाने पर निर्भर करता है. अगर जवाब मान्य है, तो इसे readResponseAsJSON को पास कर दिया जाता है.

तीसरा चरण. readResponseAsJSON, Response.json() तरीके का इस्तेमाल करके, रिस्पॉन्स के मुख्य हिस्से को पढ़ता है. यह तरीका, एक प्रॉमिस दिखाता है. यह प्रॉमिस, JSON में बदल जाता है. यह प्रॉमिस पूरा होने के बाद, JSON डेटा को logResult पर भेज दिया जाता है. (अगर response.json() से मिला प्रॉमिस पूरा नहीं होता है, तो catch ब्लॉक ट्रिगर हो जाता है.)

चरण 4. आखिर में, logResult, examples/animals.json को किए गए ओरिजनल अनुरोध से मिले JSON डेटा को लॉग करता है.

अधिक जानकारी के लिए

डेटा फ़ेच करने की सुविधा सिर्फ़ JSON फ़ॉर्मैट तक सीमित नहीं है. इस उदाहरण में, हम एक इमेज फ़ेच करेंगे और उसे पेज में जोड़ेंगे.

main.js में, यहां दिया गया कोड इस्तेमाल करके showImage फ़ंक्शन लिखें:

function showImage(responseAsBlob) {
  const container = document.getElementById('img-container');
  const imgElem = document.createElement('img');
  container.appendChild(imgElem);
  const imgUrl = URL.createObjectURL(responseAsBlob);
  imgElem.src = imgUrl;
}

इसके बाद, एक readResponseAsBlob फ़ंक्शन जोड़ें, जो जवाबों को Blob के तौर पर पढ़ता है:

function readResponseAsBlob(response) {
  return response.blob();
}

नीचे दिए गए कोड की मदद से, fetchImage फ़ंक्शन को अपडेट करें:

function fetchImage() {
  fetch('examples/fetching.jpg')
    .then(validateResponse)
    .then(readResponseAsBlob)
    .then(showImage)
    .catch(logError);
}

स्क्रिप्ट सेव करें और पेज को रीफ़्रेश करें. इमेज फ़ेच करें पर क्लिक करें. आपको पेज पर एक प्यारा कुत्ता स्टिक लाता हुआ दिखेगा (यह एक मज़ाक है!).

जानकारी

इस उदाहरण में, examples/fetching.jpg इमेज फ़ेच की जा रही है. पिछले अभ्यास की तरह ही, जवाब की पुष्टि validateResponse से की जाती है. इसके बाद, रिस्पॉन्स को Blob के तौर पर पढ़ा जाता है. हालांकि, पिछले सेक्शन में इसे JSON के तौर पर पढ़ा गया था. एक इमेज एलिमेंट बनाया जाता है और उसे पेज में जोड़ा जाता है. साथ ही, इमेज के src एट्रिब्यूट को, Blob को दिखाने वाले डेटा यूआरएल पर सेट किया जाता है.

ध्यान दें: यूआरएल ऑब्जेक्ट के createObjectURL() तरीके का इस्तेमाल, Blob को दिखाने वाले डेटा यूआरएल को जनरेट करने के लिए किया जाता है. यह ध्यान रखना ज़रूरी है. किसी इमेज के सोर्स को सीधे तौर पर Blob पर सेट नहीं किया जा सकता. ब्लॉब को डेटा यूआरएल में बदला जाना चाहिए.

अधिक जानकारी के लिए

यह सेक्शन, एक वैकल्पिक चैलेंज है.

fetchText फ़ंक्शन को अपडेट करके

  1. फ़ेच करें /examples/words.txt
  2. validateResponse की मदद से जवाब की पुष्टि करें
  3. जवाब को टेक्स्ट के तौर पर पढ़ें (सलाह: Response.text() देखें)
  4. और पेज पर टेक्स्ट दिखाएं

फ़ाइनल टेक्स्ट दिखाने के लिए, इस showText फ़ंक्शन का इस्तेमाल किया जा सकता है:

function showText(responseAsText) {
  const message = document.getElementById('message');
  message.textContent = responseAsText;
}

स्क्रिप्ट सेव करें और पेज को रीफ़्रेश करें. टेक्स्ट फ़ेच करें पर क्लिक करें. अगर आपने fetchText को सही तरीके से लागू किया है, तो आपको पेज पर जोड़ा गया टेक्स्ट दिखेगा.

ध्यान दें: एचटीएमएल फ़ेच करके, उसे innerHTML एट्रिब्यूट का इस्तेमाल करके जोड़ने का विकल्प उपलब्ध है. हालांकि, ऐसा करते समय सावधानी बरतें. इससे आपकी साइट पर क्रॉस-साइट स्क्रिप्टिंग के हमले हो सकते हैं!

अधिक जानकारी के लिए

डिफ़ॉल्ट रूप से, फ़ेच GET तरीके का इस्तेमाल करता है. इससे किसी खास संसाधन को वापस पाया जाता है. हालांकि, फ़ेच के लिए अन्य एचटीटीपी तरीकों का भी इस्तेमाल किया जा सकता है.

HEAD अनुरोध करना

headRequest फ़ंक्शन की जगह यह कोड डालें:

function headRequest() {
  fetch('examples/words.txt', {
    method: 'HEAD'
  })
  .then(validateResponse)
  .then(readResponseAsText)
  .then(logResult)
  .catch(logError);
}

स्क्रिप्ट सेव करें और पेज को रीफ़्रेश करें. HEAD request पर क्लिक करें. देखें कि लॉग किया गया टेक्स्ट कॉन्टेंट खाली है.

जानकारी

fetch वाले तरीके को दूसरा वैकल्पिक पैरामीटर, init मिल सकता है. इस पैरामीटर की मदद से, फ़ेच अनुरोध को कॉन्फ़िगर किया जा सकता है. जैसे, अनुरोध का तरीका, कैश मोड, क्रेडेंशियल, और अन्य.

इस उदाहरण में, हमने init पैरामीटर का इस्तेमाल करके, फ़ेच अनुरोध के तरीके को HEAD पर सेट किया है. HEAD अनुरोध, GET अनुरोधों की तरह ही होते हैं. हालांकि, जवाब का मुख्य हिस्सा खाली होता है. इस तरह के अनुरोध का इस्तेमाल तब किया जा सकता है, जब आपको किसी फ़ाइल के बारे में सिर्फ़ मेटाडेटा चाहिए, लेकिन आपको फ़ाइल का पूरा डेटा ट्रांसफ़र नहीं करना है.

ज़रूरी नहीं: किसी संसाधन का साइज़ ढूंढना

फ़ाइल का साइज़ तय करने के लिए, examples/words.txt के फ़ेच रिस्पॉन्स के हेडर देखते हैं.

जवाब headers की content-length प्रॉपर्टी को लॉग करने के लिए, headRequest फ़ंक्शन को अपडेट करें (सलाह: हेडर का दस्तावेज़ और get तरीका देखें).

कोड अपडेट करने के बाद, फ़ाइल को सेव करें और पेज को रीफ़्रेश करें. HEAD request पर क्लिक करें. कंसोल को examples/words.txt का साइज़ (बाइट में) लॉग करना चाहिए.

जानकारी

इस उदाहरण में, HEAD तरीके का इस्तेमाल करके किसी संसाधन (content-length हेडर में दिखाया गया है) के साइज़ (बाइट में) का अनुरोध किया गया है. हालांकि, इसमें संसाधन को लोड नहीं किया गया है. इसका इस्तेमाल यह तय करने के लिए किया जा सकता है कि पूरे संसाधन का अनुरोध किया जाना चाहिए या नहीं. साथ ही, इसका इस्तेमाल यह तय करने के लिए भी किया जा सकता है कि अनुरोध कैसे किया जाए.

ज़रूरी नहीं: किसी दूसरे तरीके का इस्तेमाल करके examples/words.txt का साइज़ पता करें. साथ ही, पुष्टि करें कि यह रिस्पॉन्स हेडर में मौजूद वैल्यू से मेल खाता हो. अपने ऑपरेटिंग सिस्टम के हिसाब से, यह पता करें कि ऐसा कैसे किया जा सकता है. कमांड लाइन का इस्तेमाल करने पर, आपको बोनस पॉइंट मिलेंगे!

अधिक जानकारी के लिए

फ़ेच, POST अनुरोधों के साथ भी डेटा भेज सकता है.

इको सर्वर सेट अप करना

इस उदाहरण के लिए, आपको एक इको सर्वर चलाना होगा. fetch-api-lab/app/ डायरेक्ट्री से यह कमांड चलाएं. अगर localhost:8081 सर्वर ने कमांड लाइन को ब्लॉक कर दिया है, तो नई कमांड लाइन विंडो या टैब खोलें:

node echo-servers/cors-server.js

यह कमांड, localhost:5000/ पर एक सामान्य सर्वर शुरू करती है. यह सर्वर, इसे भेजे गए अनुरोधों को वापस भेजता है.

ctrl+c की मदद से, इस सर्वर को कभी भी बंद किया जा सकता है.

POST अनुरोध करना

postRequest फ़ंक्शन को इस कोड से बदलें. अगर आपने सेक्शन 4 पूरा नहीं किया है, तो पक्का करें कि आपने showText फ़ंक्शन को सेक्शन 4 में तय किया हो:

function postRequest() {
  fetch('http://localhost:5000/', {
    method: 'POST',
    body: 'name=david&message=hello'
  })
    .then(validateResponse)
    .then(readResponseAsText)
    .then(showText)
    .catch(logError);
}

स्क्रिप्ट सेव करें और पेज को रीफ़्रेश करें. POST request पर क्लिक करें. पेज पर भेजे गए अनुरोध को देखें. इसमें नाम और मैसेज होना चाहिए. ध्यान दें कि हमें फ़ॉर्म से अभी तक डेटा नहीं मिल रहा है.

जानकारी

फ़ेच के साथ POST अनुरोध करने के लिए, हम init पैरामीटर का इस्तेमाल करके, तरीका तय करते हैं. यह ठीक वैसा ही है जैसे हमने पिछले सेक्शन में HEAD तरीका सेट किया था. यहां हम अनुरोध का मुख्य हिस्सा भी सेट करते हैं. इस मामले में, यह एक सामान्य स्ट्रिंग है. मुख्य हिस्सा वह डेटा होता है जिसे हमें भेजना होता है.

ध्यान दें: प्रोडक्शन में, उपयोगकर्ता के संवेदनशील डेटा को हमेशा एन्क्रिप्ट (सुरक्षित) करें.

जब डेटा को localhost:5000/ पर POST अनुरोध के तौर पर भेजा जाता है, तो अनुरोध को जवाब के तौर पर वापस भेजा जाता है. इसके बाद, validateResponse की मदद से जवाब की पुष्टि की जाती है. साथ ही, इसे टेक्स्ट के तौर पर पढ़ा जाता है और पेज पर दिखाया जाता है.

असल में, यह सर्वर तीसरे पक्ष के एपीआई को दिखाता है.

ज़रूरी नहीं: FormData इंटरफ़ेस का इस्तेमाल करना

फ़ॉर्म से डेटा आसानी से पाने के लिए, FormData इंटरफ़ेस का इस्तेमाल किया जा सकता है.

postRequest फ़ंक्शन में, msg-form फ़ॉर्म एलिमेंट से एक नया FormData ऑब्जेक्ट इंस्टैंशिएट करें:

const formData = new FormData(document.getElementById('msg-form'));

इसके बाद, body पैरामीटर की वैल्यू को formData वैरिएबल से बदलें.

स्क्रिप्ट सेव करें और पेज को रीफ़्रेश करें. पेज पर मौजूद फ़ॉर्म में नाम और मैसेज फ़ील्ड भरें. इसके बाद, POST अनुरोध पर क्लिक करें. पेज पर दिखाए गए फ़ॉर्म के कॉन्टेंट को देखें.

जानकारी

FormData कंस्ट्रक्टर, एचटीएमएल form को इनपुट के तौर पर ले सकता है और FormData ऑब्जेक्ट बना सकता है. इस ऑब्जेक्ट में, फ़ॉर्म की कुंजियां और वैल्यू अपने-आप भर जाती हैं.

अधिक जानकारी के लिए

नॉन-कॉर्स इको सर्वर शुरू करना

पिछला इको सर्वर बंद करें. इसके लिए, कमांड लाइन से ctrl+c दबाएं. इसके बाद, fetch-lab-api/app/ डायरेक्ट्री से नया इको सर्वर शुरू करें. इसके लिए, यह कमांड चलाएं:

node echo-servers/no-cors-server.js

यह कमांड, एक और सामान्य इको सर्वर सेट अप करती है. इस बार, यह localhost:5001/ पर सेट अप होता है. हालांकि, इस सर्वर को क्रॉस ऑरिजिन अनुरोध स्वीकार करने के लिए कॉन्फ़िगर नहीं किया गया है.

नए सर्वर से फ़ेच करना

अब नया सर्वर localhost:5001/ पर चल रहा है. इसलिए, हम इस पर फ़ेच करने का अनुरोध भेज सकते हैं.

postRequest फ़ंक्शन को अपडेट करें, ताकि वह localhost:5000/ के बजाय localhost:5001/ से डेटा फ़ेच कर सके. कोड अपडेट करने के बाद, फ़ाइल को सेव करें, पेज को रीफ़्रेश करें, और फिर POST Request पर क्लिक करें.

आपको कंसोल में एक गड़बड़ी दिखेगी. इसमें बताया जाएगा कि क्रॉस-ऑरिजिन अनुरोध को ब्लॉक कर दिया गया है, क्योंकि सीओआरएस Access-Control-Allow-Origin हेडर मौजूद नहीं है.

postRequest फ़ंक्शन में मौजूद fetch को इस कोड से अपडेट करें. यह कोड, no-cors मोड का इस्तेमाल करता है (जैसा कि गड़बड़ी के लॉग से पता चलता है). साथ ही, यह validateResponse और readResponseAsText को कॉल करने की सुविधा हटा देता है (नीचे दी गई जानकारी देखें):

function postRequest() {
  const formData = new FormData(document.getElementById('msg-form'));
  fetch('http://localhost:5001/', {
    method: 'POST',
    body: formData,
    mode: 'no-cors'
  })
    .then(logResult)
    .catch(logError);
}

स्क्रिप्ट सेव करें और पेज को रीफ़्रेश करें. इसके बाद, मैसेज फ़ॉर्म भरें और अनुरोध पोस्ट करें पर क्लिक करें.

कंसोल में लॉग किए गए रिस्पॉन्स ऑब्जेक्ट को देखें.

जानकारी

फ़ेच (और XMLHttpRequest) एक ही ऑरिजिन की नीति का पालन करते हैं. इसका मतलब है कि ब्राउज़र, स्क्रिप्ट से क्रॉस-ऑरिजिन एचटीटीपी अनुरोधों को सीमित करते हैं. क्रॉस-ऑरिजिन अनुरोध तब होता है, जब कोई डोमेन (उदाहरण के लिए, http://foo.com/) किसी दूसरे डोमेन (उदाहरण के लिए, http://bar.com/) से किसी संसाधन का अनुरोध करता है.

ध्यान दें: अक्सर क्रॉस-ऑरिजिन अनुरोधों से जुड़ी पाबंदियों को लेकर भ्रम की स्थिति बनी रहती है. इमेज, स्टाइलशीट, और स्क्रिप्ट जैसे कई रिसॉर्स, अलग-अलग डोमेन (यानी कि क्रॉस-ऑरिजिन) से फ़ेच किए जाते हैं. हालांकि, ये एक ही ऑरिजिन से जुड़ी नीति के अपवाद हैं. अलग-अलग डोमेन से किए जाने वाले अनुरोधों पर, स्क्रिप्ट के अंदर अब भी पाबंदी है.

हमारे ऐप्लिकेशन के सर्वर का पोर्ट नंबर, दोनों इको सर्वर से अलग है. इसलिए, दोनों इको सर्वर से किए गए अनुरोधों को क्रॉस-ऑरिजिन माना जाता है. हालांकि, localhost:5000/ पर चलने वाला पहला इको सर्वर, CORS के साथ काम करने के लिए कॉन्फ़िगर किया गया है. echo-servers/cors-server.js खोलकर कॉन्फ़िगरेशन की जांच की जा सकती है. localhost:5001/ पर चल रहा नया इको सर्वर, चालू नहीं है. इसलिए, हमें गड़बड़ी का मैसेज मिलता है.

mode: no-cors का इस्तेमाल करके, ओपेक रिस्पॉन्स फ़ेच किया जा सकता है. इससे हमें जवाब मिल जाता है, लेकिन JavaScript की मदद से जवाब को ऐक्सेस नहीं किया जा सकता. इसलिए, हम validateResponse, readResponseAsText या showResponse का इस्तेमाल नहीं कर सकते. हालांकि, जवाब को अन्य एपीआई इस्तेमाल कर सकते हैं या सर्विस वर्कर इसे कैश मेमोरी में सेव कर सकता है.

अनुरोध के हेडर में बदलाव करना

Fetch, अनुरोध हेडर में बदलाव करने की सुविधा भी देता है. localhost:5001 (सीओआरएस नहीं) इको सर्वर को बंद करें और सेक्शन 6 से localhost:5000 (सीओआरएस) इको सर्वर को फिर से चालू करें:

node echo-servers/cors-server.js

postRequest फ़ंक्शन के पिछले वर्शन को वापस लाएं. यह फ़ंक्शन localhost:5000/ से डेटा फ़ेच करता है:

function postRequest() {
  const formData = new FormData(document.getElementById('msg-form'));
  fetch('http://localhost:5000/', {
    method: 'POST',
    body: formData
  })
    .then(validateResponse)
    .then(readResponseAsText)
    .then(showText)
    .catch(logError);
}

अब हेडर इंटरफ़ेस का इस्तेमाल करके, messageHeaders नाम वाले postRequest फ़ंक्शन में एक हेडर ऑब्जेक्ट बनाएं. इसमें Content-Type हेडर की वैल्यू application/json के बराबर हो.

इसके बाद, init ऑब्जेक्ट की headers प्रॉपर्टी को messageHeaders वैरिएबल के तौर पर सेट करें.

body प्रॉपर्टी को स्ट्रिंग में बदले गए JSON ऑब्जेक्ट के तौर पर अपडेट करें. जैसे:

JSON.stringify({ lab: 'fetch', status: 'fun' })

कोड अपडेट करने के बाद, फ़ाइल को सेव करें और पेज को रीफ़्रेश करें. इसके बाद, POST Request पर क्लिक करें.

ध्यान दें कि अब गूंजने वाले अनुरोध में Content-Type की application/json है. पहले यह multipart/form-data थी.

अब messageHeaders ऑब्जेक्ट में कस्टम Content-Length हेडर जोड़ें और अनुरोध को कोई भी साइज़ दें.

कोड अपडेट करने के बाद, फ़ाइल को सेव करें, पेज को रीफ़्रेश करें, और POST Request पर क्लिक करें. ध्यान दें कि इस हेडर में, अनुरोध को दोहराते समय कोई बदलाव नहीं किया गया है.

जानकारी

हेडर इंटरफ़ेस की मदद से, हेडर ऑब्जेक्ट बनाए और उनमें बदलाव किए जा सकते हैं. फ़ेच करने की सुविधा का इस्तेमाल करके, Content-Type जैसे कुछ हेडर में बदलाव किया जा सकता है. Content-Length जैसे अन्य फ़ील्ड सुरक्षित होते हैं और सुरक्षा की वजह से, इनमें बदलाव नहीं किया जा सकता.

अनुरोध के लिए पसंद के मुताबिक हेडर सेट करना

Fetch, कस्टम हेडर सेट करने की सुविधा देता है.

postRequest फ़ंक्शन में मौजूद messageHeaders ऑब्जेक्ट से Content-Length हेडर हटाएं. कस्टम हेडर X-Custom को किसी भी वैल्यू के साथ जोड़ें. उदाहरण के लिए, 'X-CUSTOM': 'hello world''.

स्क्रिप्ट को सेव करें, पेज को रीफ़्रेश करें, और फिर POST Request पर क्लिक करें.

आपको दिखेगा कि गूंजे गए अनुरोध में, जोड़ी गई X-Custom प्रॉपर्टी मौजूद है.

अब Headers ऑब्जेक्ट में Y-Custom हेडर जोड़ें. स्क्रिप्ट सेव करें, पेज को रीफ़्रेश करें, और POST अनुरोध पर क्लिक करें.

आपको कंसोल में इस तरह की गड़बड़ी दिखेगी:

Fetch API cannot load http://localhost:5000/. Request header field y-custom is not allowed by Access-Control-Allow-Headers in preflight response.

जानकारी

क्रॉस-ऑरिजिन अनुरोधों की तरह ही, कस्टम हेडर को उस सर्वर के साथ काम करना चाहिए जिससे संसाधन का अनुरोध किया गया है. इस उदाहरण में, हमारे इको सर्वर को X-Custom हेडर को स्वीकार करने के लिए कॉन्फ़िगर किया गया है, लेकिन Y-Custom हेडर को स्वीकार करने के लिए नहीं. खुद देखने के लिए, echo-servers/cors-server.js खोलें और Access-Control-Allow-Headers ढूंढें. जब भी कोई कस्टम हेडर सेट किया जाता है, तो ब्राउज़र प्रीफ़्लाइट जांच करता है. इसका मतलब है कि ब्राउज़र पहले सर्वर को OPTIONS अनुरोध भेजता है, ताकि यह पता चल सके कि सर्वर को किन एचटीटीपी तरीकों और हेडर का इस्तेमाल करने की अनुमति है. अगर सर्वर को मूल अनुरोध के तरीके और हेडर स्वीकार करने के लिए कॉन्फ़िगर किया गया है, तो इसे भेजा जाता है. ऐसा न होने पर, गड़बड़ी का मैसेज दिखता है.

अधिक जानकारी के लिए

सॉल्यूशन कोड

काम करने वाले कोड की कॉपी पाने के लिए, solution फ़ोल्डर पर जाएं.

अब आपको Fetch API इस्तेमाल करने का तरीका पता चल गया है!

संसाधन

PWA ट्रेनिंग कोर्स में मौजूद सभी कोडलैब देखने के लिए, कोर्स का वेलकम कोडलैब देखें/