Fetch/XMLHttpRequest في JavaScript

Fetch/XMLHttpRequest في JavaScript

تشرح هذه المقالة Fetch/XMLHttpRequest في JavaScript۔

YouTube Video

javascript-html-fetch-xhr.html
  1<!DOCTYPE html>
  2<html lang="en">
  3<head>
  4  <meta charset="UTF-8">
  5  <title>JavaScript &amp; HTML</title>
  6  <style>
  7    * {
  8        box-sizing: border-box;
  9    }
 10
 11    body {
 12        margin: 0;
 13        padding: 1em;
 14        padding-bottom: 10em;
 15        font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
 16        background-color: #f7f9fc;
 17        color: #333;
 18        line-height: 1.6;
 19    }
 20
 21    .container {
 22        max-width: 800px;
 23        margin: 0 auto;
 24        padding: 1em;
 25        background-color: #ffffff;
 26        border: 1px solid #ccc;
 27        border-radius: 10px;
 28        box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
 29    }
 30
 31    .container-flex {
 32        display: flex;
 33        flex-wrap: wrap;
 34        gap: 2em;
 35        max-width: 1000px;
 36        margin: 0 auto;
 37        padding: 1em;
 38        background-color: #ffffff;
 39        border: 1px solid #ccc;
 40        border-radius: 10px;
 41        box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
 42    }
 43
 44    .left-column, .right-column {
 45        flex: 1 1 200px;
 46        min-width: 200px;
 47    }
 48
 49    h1, h2 {
 50        font-size: 1.2rem;
 51        color: #007bff;
 52        margin-top: 0.5em;
 53        margin-bottom: 0.5em;
 54        border-left: 5px solid #007bff;
 55        padding-left: 0.6em;
 56        background-color: #e9f2ff;
 57    }
 58
 59    button {
 60        display: block;
 61        margin: 1em auto;
 62        padding: 0.75em 1.5em;
 63        font-size: 1rem;
 64        background-color: #007bff;
 65        color: white;
 66        border: none;
 67        border-radius: 6px;
 68        cursor: pointer;
 69        transition: background-color 0.3s ease;
 70    }
 71
 72    button:hover {
 73        background-color: #0056b3;
 74    }
 75
 76    #output {
 77        margin-top: 1em;
 78        background-color: #1e1e1e;
 79        color: #0f0;
 80        padding: 1em;
 81        border-radius: 8px;
 82        min-height: 200px;
 83        font-family: Consolas, monospace;
 84        font-size: 0.95rem;
 85        overflow-y: auto;
 86        white-space: pre-wrap;
 87    }
 88
 89    .highlight {
 90        outline: 3px solid #ffc107; /* yellow border */
 91        background-color: #fff8e1;  /* soft yellow background */
 92        transition: background-color 0.3s ease, outline 0.3s ease;
 93    }
 94
 95    .active {
 96        background-color: #28a745; /* green background */
 97        color: #fff;
 98        box-shadow: 0 0 10px rgba(40, 167, 69, 0.5);
 99        transition: background-color 0.3s ease, box-shadow 0.3s ease;
100    }
101  </style>
102</head>
103<body>
104    <div class="container">
105        <h1>JavaScript Console</h1>
106        <button id="executeBtn">Execute</button>
107        <div id="output"></div>
108    </div>
109
110    <script>
111        // Override console.log to display messages in the #output element
112        (function () {
113            // Override console.log
114            const originalLog = console.log;
115            console.log = function (...args) {
116                originalLog.apply(console, args);
117                const message = document.createElement('div');
118                message.textContent = args.map(String).join(' ');
119                output.appendChild(message);
120            };
121
122            // Override console.error
123            const originalError = console.error;
124            console.error = function (...args) {
125                originalError.apply(console, args);
126                const message = document.createElement('div');
127                message.textContent = args.map(String).join(' ');
128                message.style.color = 'red'; // Color error messages red
129                output.appendChild(message);
130            };
131        })();
132
133        document.getElementById('executeBtn').addEventListener('click', () => {
134            // Prevent multiple loads
135            if (document.getElementById('externalScript')) return;
136
137            const script = document.createElement('script');
138            script.src = 'javascript-html-fetch-xhr.js';
139            script.id = 'externalScript';
140            //script.onload = () => console.log('javascript-html-fetch-xhr.js loaded and executed.');
141            //script.onerror = () => console.log('Failed to load javascript-html-fetch-xhr.js.');
142            document.body.appendChild(script);
143        });
144    </script>
145</body>
146</html>

Fetch/XMLHttpRequest في JavaScript

يستخدم كل من Fetch و XMLHttpRequest (XHR) في JavaScript لإرسال طلبات HTTP واسترداد البيانات من الخادم۔

Fetch API

Fetch API هي طريقة حديثة لمعالجة طلبات HTTP، تم تصميمها كبديل لـ XHR۔ إنها واجهة برمجة تطبيقات غير متزامنة تعتمد على Promises، مما يتيح معالجة أبسط وأكثر مرونة للطلبات۔

الاستخدام

 1fetch('http://127.0.0.1:3000/example.json')
 2    .then((response) => {
 3        if (!response.ok) {
 4            throw new Error('HTTP error: ' + response.status);
 5        }
 6        return response.json();  // Parse the response as JSON
 7    })
 8    .then((data) => {
 9        console.log(data);  // Use the fetched data
10        console.log(JSON.stringify(data));
11    })
12    .catch((error) => {
13        console.error('An error occurred:', error);  // Error handling
14    });
  • يرسل هذا الكود طلب GET إلى عنوان الـURL المحدد باستخدام Fetch API، ويعالج الاستجابة كـ JSON، ويعرض النتيجة أو يعرض خطأً عند حدوثه.۔

الميزات

يحتوي Fetch API على الميزات التالية:۔

  • يعتمد على الـPromise يمكن إدارة العمليات غير المتزامنة باستخدام Promises، مما يجعل الكود أكثر وضوحًا وأسهل قراءة.۔
  • سهولة معالجة الأخطاء يمكن معالجة الأخطاء بسهولة باستخدام كتلة catch
  • التحليل باستخدام طرق مثل response.json() يمكن معالجة بيانات الاستجابة بسهولة بصيغة JSON أو نصية.۔
  • دعم CORS Fetch يعمل وفقًا لقواعد مشاركة الموارد بين المصادر (CORS).۔
  • تهيئة مرنة للطلبات ليس فقط GET/POST، بل يمكن أيضًا تهيئة طرق HTTP مثل PUT وDELETE بسهولة.۔

مثال: طلب POST

 1fetch('http://127.0.0.1:3000/example.json', {
 2        method: 'POST',
 3        headers: {
 4            'Content-Type': 'application/json'
 5        },
 6        body: JSON.stringify({ name: 'Alice', age: 25 })  // Send the request body as JSON
 7    })
 8    .then(response => response.json())
 9    .then(data => console.log(JSON.stringify(data)))
10    .catch(error => console.error('Error:', error));
  • يرسل هذا الكود طلب POST يحتوي على بيانات JSON، ثم يستقبل ويعرض الاستجابة من الخادم كـ JSON.۔

العيوب

يحتوي Fetch API على العيوب التالية:۔

  • التوافق مع المتصفحات المتصفحات القديمة (خاصة IE11) لا تدعم Fetch API
  • صعوبة في إجراء التحكم الدقيق بالمقارنة مع XHR، فهو غير مناسب للتحكم على المستوى المنخفض مثل التعامل مع أحداث التقدم.۔

XMLHttpRequest(XHR)

XMLHttpRequest هي واجهة برمجة تطبيقات تم استخدامها لفترة طويلة لمعالجة طلبات HTTP وتم استخدامها على نطاق واسع كأساس لـ AJAX (JavaScript غير المتزامن و XML)۔ تُمكن من الاتصال غير المتزامن، مما يسمح باسترداد البيانات من الخادم دون إعادة تحميل الصفحة بأكملها۔

الاستخدام

 1const xhr = new XMLHttpRequest();
 2xhr.open('GET', 'http://127.0.0.1:3000/example.json', true);
 3xhr.onreadystatechange = function() {
 4    if (xhr.readyState === 4 && xhr.status === 200) {
 5        const data = JSON.parse(xhr.responseText);  // Parse the response as JSON
 6        console.log(data);  // Use the data
 7        console.log(JSON.stringify(data));
 8    }
 9};
10xhr.send();  // Send the request
  • يرسل هذا الكود طلب GET باستخدام XMLHttpRequest، ويحلل استجابة JSON المستلمة، ويعرضها.۔

الميزات

يحتوي XMLHttpRequest على الخصائص التالية:۔

  • يعتمد على عمليات الاسترجاع (Callbacks) تُستخدم دوال رد النداء مثل onreadystatechange لمراقبة اكتمال أو تقدم الطلب.۔
  • مراقبة رموز الحالة والحالات الجاهزة يمكن التحقق من حالة الطلب باستخدام xhr.readyState و xhr.status
  • توافق واسع يعمل حتى على المتصفحات القديمة.۔
  • مراقبة تقدم الطلب يمكن مراقبة التقدم باستخدام أحداث مثل xhr.upload.onprogress

مثال: طلب POST

 1const xhr = new XMLHttpRequest();
 2xhr.open('POST', 'http://127.0.0.1:3000/example.json', true);
 3xhr.setRequestHeader('Content-Type', 'application/json');
 4xhr.onreadystatechange = function() {
 5    if (xhr.readyState === 4 && xhr.status === 200) {
 6        const data = JSON.parse(xhr.responseText);
 7        console.log(data);
 8        console.log(JSON.stringify(data));
 9    }
10};
11xhr.send(JSON.stringify({ name: 'Alice', age: 25 }));  // Send the data
  • يرسل هذا الكود طلب POST مع بيانات JSON باستخدام XMLHttpRequest، ويستقبل الاستجابة ويعرضها.۔

العيوب

يحتوي XMLHttpRequest على العيوب التالية:۔

  • تعقيد الكود إدارة العمليات غير المتزامنة باستخدام دوال رد النداء غالبًا ما تكون معقدة.۔
  • لا يوجد دعم أصلي للـPromise نظرًا لعدم دعم الـPromises بشكل افتراضي، تصبح معالجة العمليات غير المتزامنة أكثر تعقيدًا قليلاً.۔

مقارنة بين Fetch API و XMLHttpRequest

الميزات Fetch API XMLHttpRequest (XHR)
المعالجة غير المتزامنة بسيطة مع الوعود (Promises) تتطلب وظائف استرجاع
معالجة الأخطاء يمكن إدارتها باستخدام .catch() التحقق من حالة readyState
أحداث التقدم غير مدعومة تتم معالجتها باستخدام onprogress
دعم المصدر المتقاطع (CORS) يدعم CORS تلقائياً يدعم CORS
دعم المتصفح غير مدعوم في IE11 وما قبله متوافق مع المتصفحات القديمة
دقة التحكم بسيط وبديهي يتيح التحكم الدقيق

الملخص

  • Fetch API يوفر طلبات HTTP بسيطة ومرنة تعتمد على الوعود (Promises)، ويوصى به في المتصفحات الحديثة۔

يمكنك متابعة المقالة أعلاه باستخدام Visual Studio Code على قناتنا على YouTube.۔ يرجى التحقق من القناة على YouTube أيضًا.۔

YouTube Video