Generic selectors
Exact matches only
Search in title
Search in content
Post Type Selectors

JavaScript – Asynchronous Programming – fetch

באמצעות fetch נוכל לנהל בקשות HTTP בצורה אסינכרונית. במאמר זה נלמד ונכיר את ה-api של fetch וכל היכולות של המתודה.

ה-api של fetch הוא למעשה ממשק (interface) אשר מאפשר לנו לעבוד עם בקשות HTML דרך הדפדפן.
בחלק השני של המדריך – Promise, עבדנו עם אובייקט XMLHttpRequest על מנת לבצע פעולה זו,
באמצעות fetch נוכל לבצע את אותן האופרציות תוך כתיבת קוד נקי וקריא יותר.

ניהול בקשות באמצעות ()fetch

ראשית, בואו נתבונן בתחביר של fetch – מדובר במתודה ולה 2 העמסות:

JavaScript - fetch
JavaScript – fetch
  • resource – נשלח את המקור שברצוננו "לתפוס" (fetch) כארגומנט,
    הערך חייב להיות מחרוזת (string) אשר מכילה את כתובת ה-url הרצויה או האובייקט הרצוי.

 

  • options – אין חובה להוסיף פרמטר זה.
    זהו אובייקט אשר מכיל אפשרויות שנרצה להחיל על הבקשה, נוכל להשתמש באפשרויות הבאות:

    • method – סוג הבקשה (POST/GET).
    • headers – אובייקט רשימת headers.
    • body –  body שנרצה להוסיף לבקשה.
    • mode – סוג הבקשה, nocors למשל ימנע מהמתודה להיות משהו שהוא לא POST, GET או HEAD.
    • credentials – מגדיר מה הדפדפן יעשה עם cookies, HTTP authentication וכו'.
    • omit – מורה לדפדפן להתעלם מ-credentials שהגיעו מהבקשה.
    • cache – מחרוזת אשר מגדירה איך הבקשה תתנהל מול ה-cache של הדפדפן.
      ניתן לתת את הערכים – default,no-store,reload,no-cache,force-cache, ו-only-if-cached.
    • redirect – מגדיר כיצד להתנהל מול תשובת redirect, כאשר follow יפנה באופן אוטומטי ל-redirect,
      error יצא וישלח שגיאה במידה וה-redirect נכשל.

 

שליחת בקשה

הערך החוזר של המתודה ()fetch יהיה Promise, אם כך, נוכל להשתמש ב-then ו-catch על מנת לטפל ב-Promise.
שימו לב ל-Code Snippet הבא שיציג את התחביר הבסיסי לשליחת בקשה וטיפול:

fetch(url)
    .then(response => {
        // מטפל בתגובה שנתקבלה
    })
    .catch(error => {
        // מטפל במצב שנתקבלה שגיאה
    });

כלומר שבמידה ונתקבל resolve, נקבל אובייקט Promise כתגובה לבקשה ששלחנו,
שימו לב לשורה 2, בתוך ה-then, אנו מטפלים ב-response (תגובה) שנתקבלה.

קריאה וטיפול ב-response שנתקבל כתגובה לבקשה

response הוא אובייקט אשר לו מספר מאפיינים מתודות שימושיים שנוכל להיעזר בהם על מנת לטפל בבקשות,
נבאר את חלקם:

מאפיינים

  • Response.ok – ערך בוליאני אשר מסמל אם הבקשה החזירה resolve או נכשלה.
  • Response.status – מחזיר קוד שמסמל את סטטוס הבקשה – 400 נכשל, 200 מוצלח, 404 לא נמצא וכו'.
  • Response.statusText– מחזיר את הטקסט שנובע מסטטוס הבקשה – למשל ok לסטטוס 200.
  • Response.url – כתובת ה-url של ה-response.

מתודות

  • ()Response.blob – מחזיר Promise שה-resolve שלה יהיה אובייקט דמוי קובץ (תמונה למשל).
  • ()Response.json – מחזיר Promise שה-resolve שלה יהיה תוצאת המרה של טקסט ל-json (כלומר parse).
  • ()Response.text – מחזיר Promise שה-resolve שלה יהיה טקסטואלי (string).
  • ()Response.clone – מחזיר Promise שה-resolve שלה יהיה העתק של אובייקט ה-response המקורי.
  • ()Response.redirect – מחזיר Promise שה-resolve שלה יהיה response מהפניה לכתובת url אחרת.

 

קיימות מתודות ומאפיינים נוספים למחלקת Response, לקריאה מורחבת יש ללחוץ כאן.

כעת, מה שנעשה זה לייבא תמונה של פוקימון כלשהו מתוך ה-api של פוקימונים,
נוכל לממש את המתודה ()blob לשם כך:

const myImage = document.querySelector('img');

const myRequest = new Request('https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/132.png');

fetch(myRequest)
  .then((response) =>; {
    if (!response.ok) {
      throw new Error(`HTTP error! Status: ${response.status}`);
    }
    return response.blob();
  })
  .then((response) =>; {
    myImage.src = URL.createObjectURL(response);
  });

שימו לב כי ה-response שנתקבל מפעולת ה-fetch שביצענו היה מוצלח (resolve),
ולכן לא נכנסנו לתוך ה-if, מה שחזור לנו זה ה-resolve (תמונה במקרה זה) באמצעות המתודה ()blob (שורה 10).

JavaScript - fetch - blob
JavaScript – fetch – blob

()fetch עם async ו-await

כמובן שנוכל ואף נרצה גם לשלב את fetch עם async ו-await.
כדוגמא נכתוב מחדש את הקטע הקודם  בצורה שונה ובתוך פונקציה:

const myImage = document.querySelector('img');

async function fetchPokemon() {
  let response = await fetch('https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/132.png');
  if (response.status === 200) {
    let pic = await response.blob();
    return myImage.src = URL.createObjectURL(pic);
  }
  throw new Error(response.statusText);
}

fetchPokemon();

אם תריצו תוכנית זו, תוכלו לראות כי התוצאה תהיה זהה.

JavaScript - fetch - blob
JavaScript – fetch – blob

()fetch בעבודה מול קבצי JSON

נניח וברשותנו קובץ JSON מסוים, שברצוננו לבצע עליו פעולות בצורה אסינכרונית שלא תפריע למשתמש בדף ה-HTML שלנו.
נכתוב מימוש שידגים את כל מה שלמדנו בחלק זה של המדריך.
ראשית צרו אלמנט div בדף ה-HTML שלכם ושייכו אותו לקלאס בשם container,
כמו כן, צרו כפתור שכאשר המשתמש ילחץ עליו – יציג את פרטי המשתמשים:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link rel="stylesheet" href="styles.css">
</head>
<body>
    <h1>Users</h1>
    <button id="btn">click</button>
    <div class="container">
    </div>
</body>
</html>

כדוגמא נשתמש בקובץ JSON שניצור בעצמנו.
ה-JSON שלנו יהיה קובץ אשר מחזיק שמות משתמשים:

[
    {
        "username": "john42",
        "firstName": "John",
        "lastName": "Doe",
        "gender": "Male",
        "pokemons": 5
    },
    {
        "username": "lindaD",
        "firstName": "linda",
        "lastName": "Doe",
        "gender": "Female",
        "pokemons": 12
    }
]

בקובץ ה-JavaScript נשתמש ב-fetch על מנת לשלוף את המידע מקובץ ה-JSON ולהציגו על גבי דף ה-HTML שלנו.
נוכל אם כך ליצור פונקציה אסינכרונית אחת לשליפת הנתונים ואחת נוספת להצגתם כאשר המשתמש לוחץ על כפתור.
שימו לב לסקריפט הבא שידגים זאת:

const container = document.querySelector('.container');
const btn = document.querySelector('#btn');

async function getUsers() {
  let url = 'users.json';
  try {
    let res = await fetch(url);
    return await res.json();
  }
  catch (error) {
    console.log(error);
  }
}

btn.addEventListener('click', async _ => {
  let users = await getUsers();
  let myDiv = '';
  users.forEach(user => {
    let htmlSegment = `<div class="user">
                          <h2>${user.firstName} ${user.lastName}</h2>
                          <p>Pokemons : ${user.pokemons}</p>
                      </div>`;
    myDiv += htmlSegment;
  });
  container.innerHTML = myDiv;
});

כעת נבאר את התוכנית על כל שלביה.
כאשר המשתמש לחץ על הכפתור ביצענו await לפונקציה שקראנו לה getUsers,
פונקציה זו מכילה את ה-fetch לקובץ ה-JSON שייצרנו לפני כן (שורה 7).
השתמשנו ב-try ו-catcth על מנת לעשות זאת, כך שלא נקרוס במידה והקובץ לא נמצא.
במידה והתקבל resolve, נהפוך את ה-response שלנו ל-JSON (שורה 8) באמצעות המתודה ()response.json.
לאחר מכן רצנו בלולאה (שורה 18) על אובייקט ה-JSON שלנו והכנסנו את המידע של כל משתמש אל המשתנה myDiv.
לבסוף הכנסנו את כל המידע שאספנו מקובץ ה-JSON אל דף ה-HTML שלנו והצגנו אותו (שורה 25).

כעת, אם תיצרו קובץ CSS ותעצבו את התוכנית כרצונכם, תוכלו לקבל את תוצאה דומה לזו:

לקריאה מורחבת על ה- fetch api יש ללחוץ כאן.

רוצים לשתף את המדריך?

אהבתכם את המדריך? פתר לכם תקלה?

גולשים יקרים, רוב התכנים המוצגים באתר נכתבים בהתנדבות מלאה מתוך כוונה להנגיש מידע עבורכם. אם נתקלתם במדריך חינמי שפתר לכם תקלה או לימד אתכם משהו חדש שלא ידעתם, וברצונכם לתגמל את כותב המדריך או סתם להזמין אותו לכוס קפה, הינכם יותר ממוזמנים לתרום.

כתיבת תגובה

הזמינו אותי לכוס קפה
buy me coffee

אהבתכם את המדריך? פתר לכם תקלה? הזמינו את כותב המדריך לכוס קפה

גולשים יקרים, רוב התכנים המוצגים באתר נכתבים בהתנדבות מלאה מתוך כוונה להנגיש מידע עבורכם. אם נתקלתם במדריך חינמי שפתר לכם תקלה או לימד אתכם משהו חדש שלא ידעתם, וברצונכם לתגמל את כותב המדריך או סתם להזמין אותו לכוס קפה, הינכם יותר ממוזמנים לתרום.