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. זוהי API אסינכרונית המבוססת על 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 ניתן לנהל פעולות אסינכרוניות עם Promise-ים, מה שהופך את הקוד לנקי וקל לקריאה.
  • טיפול קל בשגיאות ניתן לטפל בשגיאות בקלות באמצעות בלוק 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, הוא לא מתאים לשליטה ברמה נמוכה כמו טיפול באירועי התקדמות (progress events).

XMLHttpRequest(XHR)

XMLHttpRequest הוא API ששימש במשך זמן רב לטיפול בבקשות 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 יש את התכונות הבאות:.

  • מבוסס על Callback פונקציות callback כמו 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 יש את החסרונות הבאים:.

  • מורכבות קוד ניהול עיבוד אסינכרוני עם פונקציות callback נוטה להיות מורכב.
  • אין תמיכה ב-Promise באופן מובנה מכיוון ש-Promises אינם נתמכים כברירת מחדל, עיבוד אסינכרוני נהיה מסורבל יותר.

השוואה בין Fetch API לבין XMLHttpRequest

תכונות Fetch API XMLHttpRequest (XHR)
עיבוד אסינכרוני פשוט עם Promises דורש פונקציות callback
ניהול שגיאות ניתן לניהול עם .catch() בדיקת מצב readyState
אירועי התקדמות לא נתמך מנוהל עם onprogress
תמיכה במעבר מקורות (Cross-origin) תומך אוטומטית ב-CORS תומך ב-CORS
תמיכה בדפדפנים לא נתמך ב-IE11 ובגרסאות ישנות יותר תואם דפדפנים ישנים
רמת פירוט שליטה פשוט ואינטואיטיבי מאפשר שליטה מפורטת

סיכום

  • Fetch API מספק בקשות HTTP פשוטות וגמישות המבוססות על Promises ומומלץ לדפדפנים מודרניים.

תוכלו לעקוב אחר המאמר שלמעלה באמצעות Visual Studio Code בערוץ היוטיוב שלנו. נא לבדוק גם את ערוץ היוטיוב.

YouTube Video