फ़ेच() के बारे में जानकारी

फ़ेच() एपीआई, विंडो ऑब्जेक्ट में लैंडिंग कर रहा है और XHRs को बदलना चाहता है

मैट गौंट

बहुत लंबा XMLHttpRequest

fetch() आपको XMLHttpRequest (XHR) से मिलते-जुलते नेटवर्क अनुरोध करने की अनुमति देता है. मुख्य अंतर यह है कि Fetch API, Promises का इस्तेमाल करता है, जो एक आसान और साफ़ एपीआई चालू करता है. साथ ही, कॉलबैक की समस्या से बचा जाता है और XMLHttpRequest के जटिल एपीआई को याद रखने की ज़रूरत होती है.

ब्राउज़र सहायता

  • 42
  • 14
  • 39
  • 10.1

सोर्स

Chrome 40 के बाद से फ़ेच एपीआई सर्विस वर्कर ग्लोबल स्कोप में उपलब्ध है. हालांकि, इसे Chrome 42 में विंडो स्कोप में चालू किया जाएगा. इसके बजाय, GitHub की ओर से पॉलीफ़िल फ़ेच करने का एक ऐसा तरीका है जिसका इस्तेमाल आज किया जा सकता है.

अगर आपने पहले कभी प्रॉमिस का इस्तेमाल नहीं किया है, तो JavaScript प्रॉमिसेस के बारे में जानकारी देखें.

फ़ेच करने का बुनियादी अनुरोध

पहले, लागू किए गए एक आसान उदाहरण की तुलना XMLHttpRequest और फिर fetch से करते हैं. हम सिर्फ़ यूआरएल का अनुरोध करना चाहते हैं, उसका जवाब पाना चाहते हैं, और उसे JSON के तौर पर पार्स करना चाहते हैं.

XMLHttpRequest

कामयाब और गड़बड़ी के मामलों को हैंडल करने के लिए, XMLHttpRequest में दो लिसनर सेट होने चाहिए. साथ ही, इसके लिए open() और send() को कॉल करना होगा. एमडीएन वाले दस्तावेज़ों का उदाहरण.

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);
    });

जवाब को JSON के तौर पर पार्स करने से पहले, हम यह जांचते हैं कि रिस्पॉन्स का स्टेटस 200 है या नहीं.

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 टाइप का होगा. साथ ही, इस बात पर कोई पाबंदी नहीं होगी कि जवाब से किस तरह का डेटा देखा जा सकता है.

अगर किसी ऐसे ऑरिजिन पर मौजूद रिसॉर्स के लिए अनुरोध किया जाता है जो सीओआरएस हेडर दिखाता है, तो cors टाइप होता है. cors और basic जवाब करीब-करीब एक जैसे हैं. हालांकि, cors रिस्पॉन्स, Cache-Control, Content-Language, Content-Type, Expires, Last-Modified, और Pragma वाले उन हेडर को सीमित कर देता है जिन्हें आप देख सकते हैं.

opaque रिस्पॉन्स, किसी ऐसे संसाधन के लिए किए गए अनुरोध के लिए है जो किसी अलग ऑरिजिन पर है और जो सीओआरएस हेडर नहीं दिखाता है. ओपेक रिस्पॉन्स की मदद से, न तो अनुरोध के रिस्पॉन्स में भेजे गए डेटा को पढ़ा जा सकता है और न ही उसकी स्थिति को देखा जा सकता है. इसका मतलब है कि हम यह जांच नहीं कर सकते कि अनुरोध स्वीकार किया गया है या नहीं.

आप फ़ेच करने के अनुरोध के लिए ऐसा मोड तय कर सकते हैं जिससे सिर्फ़ कुछ अनुरोधों का समाधान हो सके. नीचे दिए गए मोड सेट किए जा सकते हैं:

  • same-origin सिर्फ़ एक ही ऑरिजिन पर एसेट के अनुरोधों को पूरा करता है, दूसरे सभी अनुरोध अस्वीकार कर दिए जाएंगे.
  • cors एक ही ऑरिजिन और अन्य ऑरिजिन वाली ऐसी एसेट के लिए अनुरोध करने की अनुमति देगा जो सही सीओआर हेडर दिखाती हैं.
  • cors-with-forced-preflight, असल अनुरोध करने से पहले हमेशा प्रीफ़्लाइट जांच करेगा.
  • no-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)
    });

वादे चेन करना

वादों की एक बड़ी सुविधा यह है कि उन्हें एक साथ जोड़कर दिखाया जा सकता है. इससे फ़ेच करने के लिए, सभी अनुरोधों के बीच लॉजिक शेयर किया जा सकता है.

अगर JSON API का इस्तेमाल किया जा रहा है, तो आपको स्टेटस की जांच करनी होगी और हर रिस्पॉन्स के लिए, 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 के तरीके से कॉल करके, अनुरोध के मुख्य हिस्से में कुछ पैरामीटर शामिल करते हैं.

ऐसा करने के लिए, हम fetch() के विकल्पों में method और body पैरामीटर सेट कर सकते हैं.

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'
})

अक्सर पूछे जाने वाले सवाल

मैं फ़ेच() अनुरोध को कैसे रद्द करूं?

फ़िलहाल, फ़ेच को रद्द करने का कोई तरीका नहीं है, लेकिन GitHub पर इसकी चर्चा की जा रही है. इस लिंक के लिए H/T @jaffatheoke.

क्या यहां पॉलीफ़िल है?

GitHub में फ़ेच करने के लिए एक पॉलीफ़िल है. इस बारे में बताने के लिए H/T @Nexii.

सर्विस वर्कर में "नो-कोर्स" काम क्यों करता है, लेकिन विंडो नहीं?

ऐसा सुरक्षा से जुड़ी किसी समस्या की वजह से किया गया है. इसके बारे में यहां ज़्यादा जानें.