यह कोडलैब, प्रोग्रेसिव वेब ऐप्लिकेशन डेवलप करने से जुड़े ट्रेनिंग कोर्स का हिस्सा है. इसे 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
फ़ंक्शन को अपडेट करके
- फ़ेच करें
/examples/words.txt
validateResponse
की मदद से जवाब की पुष्टि करें- जवाब को टेक्स्ट के तौर पर पढ़ें (सलाह: Response.text() देखें)
- और पेज पर टेक्स्ट दिखाएं
फ़ाइनल टेक्स्ट दिखाने के लिए, इस 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 ट्रेनिंग कोर्स में मौजूद सभी कोडलैब देखने के लिए, कोर्स का वेलकम कोडलैब देखें/