हर वेब एप्लिकेशन के मूल में *डेटा* है। डेटा कई रूप ले सकता है, लेकिन इसका मुख्य उद्देश्य हमेशा उपयोगकर्ता को जानकारी प्रदर्शित करना है। वेब एप्लिकेशन तेजी से इंटरेक्टिव और जटिल होने के साथ, उपयोगकर्ता कैसे पहुंचता है और जानकारी के साथ सहभागिता करता है, अब वेब विकास का एक महत्वपूर्ण हिस्सा है।
इस पाठ में, हम एक सर्वर से डेटा को असिंक्रोनोस रूप से प्राप्त करने का तरीका देखेंगे, और HTML को पुनः लोड किए बिना वेब पेज पर जानकारी प्रदर्शित करने के लिए इस डेटा का उपयोग करेंगे।
इस पाठ के लिए आपको वेब ऐप का [लॉगिन और पंजीकरण फॉर्म](../../2-forms/translations/README.hi.md) भाग बनाने की आवश्यकता है। आपको स्थानीय रूप से [Node.js](https://nodejs.org) और [सर्वर एपीआई चलाने](../../api/translations/README.hi.md) स्थापित करने की आवश्यकता है ताकि आपको खाता डेटा प्राप्त हो सके।
पारंपरिक वेब साइटें प्रदर्शित सामग्री को अपडेट करती हैं जब उपयोगकर्ता एक लिंक का चयन करता है या पूर्ण HTML पृष्ठ को फिर से लोड करके एक फॉर्म का उपयोग करके डेटा सबमिट करता है। हर बार नए डेटा को लोड करने की आवश्यकता होती है, वेब सर्वर एक नया HTML पृष्ठ लौटाता है जिसे ब्राउज़र द्वारा संसाधित करने की आवश्यकता होती है, वर्तमान उपयोगकर्ता कार्रवाई को बाधित करता है और पुनः लोड के दौरान इंटरैक्शन को सीमित करता है। इस वर्कफ़्लो को *मल्टी-पेज एप्लिकेशन* या *एमपीए* भी कहा जाता है।
जब वेब एप्लिकेशन अधिक जटिल और संवादात्मक होने लगे, तो [AJAX (असिंक्रोनोस जावास्क्रिप्ट और XML)](https://en.wikipedia.org/wiki/Ajax_(programming)) नामक एक नई तकनीक सामने आई। यह तकनीक वेब ऐप्स को HTML पेज को फिर से लोड किए बिना, जावास्क्रिप्ट के उपयोग से सर्वर से असिंक्रोनोस रूप से डेटा भेजने और पुनः प्राप्त करने की अनुमति देती है, जिसके परिणामस्वरूप तेज़ अपडेट और सुगम उपयोगकर्ता सहभागिता होती है। जब सर्वर से नया डेटा प्राप्त होता है, तो वर्तमान HTML पृष्ठ को [DOM](https://developer.mozilla.org/docs/Web/API/Document_Object_Melel) API का उपयोग करके जावास्क्रिप्ट के साथ भी अपडेट किया जा सकता है। समय के साथ, यह दृष्टिकोण अब एक [* सिंगल-पेज एप्लिकेशन* या *एसपीए*](https://en.wikipedia.org/wiki/Single-page_application) कहलाता है।
जब AJAX पहली बार पेश किया गया था, तो डेटा को अतुल्य रूप से लाने के लिए उपलब्ध एकमात्र API [`XMLHttpRequest`](https://developer.mozilla.org/docs/Web/API/XMLHttpRequest/Using_XMLHttpRequest) था। लेकिन आधुनिक ब्राउज़र अब अधिक सुविधाजनक और शक्तिशाली [`Fetch` API](https://developer.mozilla.org/docs/Web/API/Fetch_API) लागू करते हैं, जो प्रामिसेस का उपयोग करता है और हेरफेर करने के लिए बेहतर अनुकूल है JSON डेटा।
> जबकि सभी आधुनिक ब्राउज़र `Fetch API` का समर्थन करते हैं, यदि आप चाहते हैं कि आपका वेब एप्लिकेशन विरासत या पुराने ब्राउज़रों पर काम करे, तो यह हमेशा एक अच्छा विचार है कि [caniuse.com पर संगतता तालिका](https://caniuse.com/fetch) पहले की जाँच करें।
[पिछले पाठ में](../../2-forms/translations/README.hi.md) हमने खाता बनाने के लिए पंजीकरण फ़ॉर्म लागू किया था। अब हम किसी मौजूदा खाते का उपयोग कर लॉगिन करने के लिए कोड जोड़ेंगे और उसका डेटा प्राप्त करेंगे। `app.js` फ़ाइल खोलें और एक नया `login` फ़ंक्शन जोड़ें:
यहाँ हम `getElementById()` के साथ फॉर्म एलिमेंट को पुनः प्राप्त करके शुरू करते हैं, और फिर हम `loginForm.user.value` के साथ इनपुट से यूज़रनेम प्राप्त करते हैं। प्रत्येक प्रपत्र नियंत्रण को उसके नाम (फॉर्म का गुण के रूप में HTML में `name` विशेषता का उपयोग करके सेट) तक पहुँचा जा सकता है।
हम सर्वर से एसिंक्रोनस रूप से डेटा का अनुरोध करने के लिए `fetch` एपीआई का उपयोग करते हैं, लेकिन इस बार हमें कॉल करने के लिए URL के अलावा किसी भी अतिरिक्त पैरामीटर की आवश्यकता नहीं है, क्योंकि हम केवल डेटा क्वेरी कर रहे हैं। डिफ़ॉल्ट रूप से, 'fetch' एक [`GET`](https://developer.mozilla.org/docs/Web/HTTP/Methods/GET) HTTP अनुरोध बनाता है , जो हम यहाँ चाह रहे हैं।
✅ `encodeURIComponent()` एक फ़ंक्शन है जो URL के लिए विशेष वर्णों से बच जाता है। यदि हम इस फ़ंक्शन को कॉल नहीं करते हैं और URL में सीधे `user` वैल्यू का उपयोग करते हैं, तो संभवतः हमारे पास क्या समस्याएँ हो सकती हैं?
सबसे पहले, जैसा कि `getAccount` एक असिंक्रोनोस फ़ंक्शन है, जिसे हमें सर्वर परिणाम की प्रतीक्षा करने के लिए `await` कीवर्ड के साथ मेल खाना चाहिए। किसी भी सर्वर अनुरोध के साथ, हमें त्रुटि मामलों से भी निपटना होगा। अभी के लिए हम केवल त्रुटि प्रदर्शित करने के लिए एक लॉग संदेश जोड़ेंगे, और बाद में वापस आएँगे।
फिर हमें डेटा को कहीं स्टोर करना होगा ताकि हम बाद में इसे डैशबोर्ड इनफार्मेशन्स को प्रदर्शित कर सकें। चूंकि `account` चर अभी तक मौजूद नहीं है, हम अपनी फ़ाइल के शीर्ष पर इसके लिए एक वैश्विक चर बनाएंगे।
✅ क्या आप जानते हैं कि डिफ़ॉल्ट रूप से, आप सर्वर API को केवल उसी वेब पेज से *उसी डोमेन और पोर्ट* से कॉल कर सकते हैं जो आप देख रहे हैं? यह सुरक्षा तंत्र है जो ब्राउज़र द्वारा लागू किया जाता है। लेकिन रुकिए, हमारा वेब ऐप `localhost:3000` पर चल रहा है जबकि सर्वर एपीआई `localhost:5000` पर चल रहा है, यह काम क्यों नहीं करता है? [क्रॉस-ओरिजिनल रिसोर्स शेयरिंग (CORS)](https://developer.mozilla.org/docs/Web/HTTP/CORS) नामक तकनीक का उपयोग करके, क्रॉस-ऑरिजनल HTTP रिक्वेस्ट करना संभव है अगर सर्वर प्रतिक्रिया के लिए विशेष हेडर जोड़ता है, विशिष्ट डोमेन के लिए अपवाद की अनुमति देता है।
अब जब हमारे पास उपयोगकर्ता डेटा है, तो हमें इसे प्रदर्शित करने के लिए मौजूदा HTML को अपडेट करना होगा। हम पहले से ही जानते हैं कि DOM से एक एलेमेन्ट कैसे प्राप्त किया जा सकता है उदाहरण के लिए `document.getElementById()` का उपयोग करना। आपके पास आधार एलेमेन्ट होने के बाद, यहां कुछ API हैं जिनका उपयोग आप इसे संशोधित करने या इसमें बाल एलेमेन्ट जोड़ने के लिए कर सकते हैं:
- [`TextContent`](https://developer.mozilla.org/docs/Web/API/Node/textContent) प्रॉपर्टी का उपयोग करके आप किसी एलेमेन्ट का पाठ बदल सकते हैं। ध्यान दें कि इस मान को बदलने से सभी एलेमेन्ट के बच्चे (यदि कोई हो) को हटा देता है और प्रदान किए गए पाठ के साथ बदल देता है। जैसे, यह किसी दिए गए एलेमेन्ट के सभी बच्चों को एक खाली स्ट्रिंग `''` को निर्दिष्ट करके निकालने की एक कुशल विधि है।
- [`document.createElement()`](https://developer.mozilla.org/docs/Web/API/Document/createElement) के साथ [`append()`](https://developer.mozilla.org/docs/Web/API/ParentNode/append) विधि का उपयोग करके आप बना सकते हैं और एक या अधिक नए बाल एलेमेन्ट संलग्न करें।
✅ किसी एलेमेन्ट की प्रॉपर्टी का उपयोग करते हुए [`innerHTML`](https://developer.mozilla.org/docs/Web/API/Element/innerHTML) का उपयोग करना संभव है, लेकिन यह एक होना चाहिए [क्रॉस-साइट स्क्रिप्टिंग (XSS)](https://developer.mozilla.org/docs/Glossary/Cross-site_scripting) हमलों के कारण इसकी चपेट में आने से बचा जा सकता है।
डैशबोर्ड स्क्रीन पर जाने से पहले, एक और चीज़ है जो हमें *लॉगिन* पेज पर करनी चाहिए। वर्तमान में, यदि आप एक उपयोगकर्ता नाम के साथ लॉगिन करने की कोशिश करते हैं जो मौजूद नहीं है, तो कंसोल में एक संदेश दिखाया जाता है लेकिन एक सामान्य उपयोगकर्ता के लिए कुछ भी नहीं बदलता है और आपको नहीं पता कि क्या चल रहा है।
आइए लॉगिन फॉर्म में एक प्लेसहोल्डर एलेमेन्ट जोड़ें जहां हम एक त्रुटि संदेश प्रदर्शित कर सकते हैं यदि आवश्यक हो। लॉगिन `<button>` के ठीक पहले एक अच्छी जगह होगी:
यह `<div>` एलेमेन्ट रिक्त है, जिसका अर्थ है कि स्क्रीन पर कुछ भी प्रदर्शित नहीं किया जाएगा जब तक हम इसमें कुछ सामग्री नहीं जोड़ते। हम इसे एक `id` भी देते हैं ताकि हम इसे जावास्क्रिप्ट के साथ आसानी से प्राप्त कर सकें।
यह एक बहुत सीधा है: एक एलेमेन्ट *आईडी* और *टेक्स्ट* दिया गया है, यह DOM एलेमेन्ट के टेक्स्ट कंटेंट को `id` के मेल से अपडेट करेगा। आइए `login` फ़ंक्शन में पिछले त्रुटि संदेश के स्थान पर इस मेथड का उपयोग करें:
अब हमारे पास त्रुटि पाठ है जो नेत्रहीन रूप से दिखाई देता है, लेकिन यदि आप इसे एक स्क्रीन रीडर के साथ आज़माते हैं तो आप देखेंगे कि कुछ भी घोषित नहीं हुआ है। पाठ पाठकों के लिए गतिशील रूप से एक पृष्ठ में जोड़े जाने की घोषणा के लिए, इसे [लाइव रीजन](https://developer.mozilla.org/docs/Web/Accessibility/ARIA/ARIA_Live_Regions) नामक कुछ का उपयोग करने की आवश्यकता होगी। यहां हम एक विशिष्ट प्रकार के लाइव क्षेत्र का उपयोग करने जा रहे हैं, जिसे अलर्ट कहा जाता है:
✅ चूंकि खाता विवरण इसके नीचे की सामग्री के लिए एक शीर्षक के रूप में कार्य करता है, इसलिए इसे एक शीर्षक के रूप में शब्दार्थ के रूप में चिह्नित किया जाता है। पहुँच क्षमता के लिए [शीर्षक संरचना](https://www.nomensa.com/blog/2017/how-structure-headings-web-accessibility) के बारे में और जानें, और क्या निर्धारित करने के लिए पृष्ठ पर एक महत्वपूर्ण नज़र डालें एक शीर्षक हो सकता है।
पहले, हम जाँचते हैं कि आगे जाने से पहले हमारे पास खाता डेटा है जो हमें चाहिए। तब हम HTML को अपडेट करने के लिए पहले बनाए गए `updateElement()` फ़ंक्शन का उपयोग करते हैं।
> बैलेंस डिस्प्ले को प्रीटियर करने के लिए, हम दशमलव बिंदु के बाद 2 अंकों के साथ मान प्रदर्शित करने के लिए मजबूर करने के लिए [`toFixed (2)`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number/toFixed) विधि का उपयोग करते हैं।
अब हमें अपने `updateDashboard()` को हर बार डैशबोर्ड लोड होने पर कॉल करने की आवश्यकता है। यदि आपने पहले ही [पाठ 1 असाइनमेंट](../../1-template-route/translations/assignment.hi.md) को पूरा कर लिया है, तो यह स्ट्रेचेफोवर्ड होना चाहिए, अन्यथा आप निम्नलिखित कार्यान्वयन का उपयोग कर सकते हैं।
इस परिवर्तन के साथ, हर बार डैशबोर्ड पृष्ठ प्रदर्शित होने पर, फ़ंक्शन `updateDashboard()` कल किया जाता है। एक लॉगिन के बाद, आपको तब खाता शेष, मुद्रा और विवरण देखने में सक्षम होना चाहिए।
[पहला पाठ](../../1-template-route/translations/README.hi.md) मे हमने एचटीएमएल टेम्पलेटके साथ [`appendChild()`](https://developer.mozilla.org/docs/Web/API/Node/appendChild) मेथड को नेवीगेशनके लिए अपने एप मे लागू किया था । टेम्प्लेट छोटे भी हो सकते हैं और किसी पृष्ठ के दोहराए गए भागों को गतिशील रूप से आबाद करने के लिए उपयोग किए जा सकते हैं।
यह फ़ंक्शन ठीक वही करता है जो इसके नाम का अर्थ है: हमने पहले बनाए गए टेम्पलेट का उपयोग करके, यह एक नई तालिका पंक्ति बनाता है और लेनदेन डेटा का उपयोग करके अपनी सामग्री में भरता है। हम टेबल को आबाद करने के लिए अपने `updateDashboard()` फ़ंक्शन में इसका उपयोग करेंगे:
यहां हम उस मेथड का उपयोग करते हैं [`document.createDocumentFragment()`](https://developer.mozilla.org/docs/Web/API/Document/createDocumentFragment) जो एक नया DOM टुकड़ा बनाता है जिस पर हम काम कर सकते हैं, अंत में इसे हमारे HTML तालिका में संलग्न करने से पहले।
इस कोड के काम करने से पहले अभी भी हमें एक और काम करना है, क्योंकि हमारा `updateElement()` फ़ंक्शन वर्तमान में केवल टेक्स्ट सामग्री का सपोर्ट करता है। आइए इसके कोड को थोड़ा बदलें:
हम [`append()`](https://developer.mozilla.org/docs/Web/API/ParentNode/append) मेथड का उपयोग करते हैं क्योंकि यह टेक्स्ट या [DOM नोड्स](https://developer.mozilla.org/docs/Web/API/Node) को पेरन्ट एलेमेन्टसे जोड़ने की अनुमति देता है , जो हमारे सभी उपयोग मामलों के लिए एकदम सही है।
डैशबोर्ड पृष्ठ को वास्तविक बैंकिंग ऐप की तरह बनाने के लिए एक साथ काम करें। यदि आप पहले से ही अपने ऐप को स्टाइल करते हैं, तो डेस्कटॉप और मोबाइल डिवाइस दोनों पर अच्छी तरह से काम करते हुए [उत्तरदायी डिज़ाइन](https://developer.mozilla.org/docs/Web/Progressive_web_apps/Responsive/responsive_design_building_blocks) बनाने के लिए [मीडिया क्वेरीज़](https://developer.mozilla.org/docs/Web/CSS/Media_Queries) का उपयोग करने का प्रयास करें।