Fetch – ככה עושים AJAX היום

צריכים ליצור בקשת AJAX? אין סיבה להשתמש בדרכים הישנות. זו השיטה הטובה והנוחה ביותר.
ההבטחה הראשונה מחזירה את אובייקט ה-response, ההבטחה השניה מחזירה את אובייקט ה-JSON המתקבל.

בשנים האחרונות, ככל שהשימוש בפריימוורקים גדולים כמו Angular, react, vue ודומיהן הולך ומתרחב, כך יורד הצורך שלי לממש AJAX באופן טבעי (מה שנקרא נייטיב או ג'אווהסקריפט ונילה – כלומחר ג'אווהסקריפט שעובד ישר בשרת בלי ספריות/עזרים כמו jQuery וחבריו). לכל הפריימוורקים האלו יש את הדרכים שלהם ליצור תקשורת עם השרת המרוחק שמפשטות מאוד את התהליך המאוד מסורבל של ליצור תקשורת אסינכרונית עם השרת. במקום ליצור אובייקט XMLHttpRequest ולהתחיל להתעסק עם קודי תגובה מסוג 4 או 3 אני יכול פשוט להשתמש ב-http$ ולקרוא ל-get אם אני באנגולר (למשל).
למרות זאת, לעתים יש צורך עז כן לעשות AJAX. אם אתם כותבים קומפוננטות עצמאיות או משתמשים בפריימוורק שאין בו אבסטרקציה ל-AJAX איך עושים את זה? עם fetch. זו דרך טבעית, קלה ופשוטה לממש AJAX שנתמכת בכל דפדפן (נכון לתאריך כתיבת שורות אלו כולם חוץ מאקספלורר 11 וגם לו יש פוליפיל שעובד יפה עם babel, אז אין תירוצים).

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

בגדול, fetch הוא אובייקט גלובלי שזמין בכל מקום בקוד שלנו ומקבל שני ארגומנטים – לאן אנחנו רוצים ליצור תקשורת וארגומנט נוסף של אפשרויות. נדגים עם האפשרות הפשוטה ביותר. בואו למשל נניח שאני רוצה ליצור קשר עם ה-API הנוח להפליא של בדיחות צ'אק נוריס: https://api.chucknorris.io/jokes/random ה-API הזה, למי שלא מכיר, מחזיר בדיחה אקראית על צ'אק נוריס בכל פעם. אם אני רוצה לממש את זה, אני אצטרך לעשות משהו כזה:


fetch('https://api.icndb.com/jokes/random1http://api.icndb.com/jokes/random', {})
  .then((response) => {
    return response.json();
  })
  .then((jsonObject) => {
    document.write(jsonObject.value.joke);
  });

בואו ונסביר לפני שמישהו יתעלף. קודם כל אנחנו מתחילים ב-fetch. פונקציה גלובלית שלא צריך לעשות כלום בשבילה. היא נמצאת שם. היא מקבל שני ארגומנטים. הראשון הוא האתר שאליו אנחנו מתחברים. אם ניכנס עם הדפדפן נגלה שאנחנו מקבלים אובייקט JSON. השני הוא אובייקט ריק. במידה ויש לנו הצלחה, fetch מחזיר promise שמעבירה אובייקט שנקרא response, על מנת לראות מה קורה אם היא מתממשת אני צריך להשתמש ב-then. מה שבא אחר כך זו פונקצית חץ של ECMAScript 6. אם אתם לא יודעים מה זה, הגיע הזמן ללמוד. כולם משתמשים בזה. בגדול זה כמו לכתוב:


 .then(funtion(response) {
    return response.json();
  })

מה זה ה-response הזה? זה אובייקט של התגובה מהשרת. יש לנו מספר תכונות ומספר מתודות. כל מתודה שלו גם מחזירה promise. במקרה הזה השתמשתי במתודת json שמחזירה promise שהיא אובייקט ה-JSON המתקבל. כיוון שקל לשרשר promise הקוד נראה אלגנטי. בשרשור האחרון, של ה-promise שמתקבל מה-response.json, יש לי את אובייקט ה-JSON שמתקבל מהשרת ואני יכול לעשות איתו מה שאני רוצה.

לא מבינים עדיין? הנה התרשים שמסביר:

ההבטחה הראשונה מחזירה את אובייקט ה-response, ההבטחה השניה מחזירה את אובייקט ה-JSON המתקבל.
ההבטחה הראשונה מחזירה את אובייקט ה-response, ההבטחה השניה מחזירה את אובייקט ה-JSON המתקבל.

ואם מישהו רוצה לשחק עם זה, הנה דוגמה חיה מ-codepen:

See the Pen FETCH example by Ran Bar-Zik (@barzik) on CodePen.

טיפול בשגיאות

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


fetch('https://fail-api.lo-po.com/it-is-not-there', {})
  .then((response) => {
    return response.json();
  })
  .then((jsonObject) => {
    document.write(jsonObject.value.joke);
  })
  .catch((error) => {
    document.write(error);
  });


הנה הדוגמה החיה שבה גם אפשר לשחק. ניתן להעביר את ה-catch במעלה שרשרת ה-promises אבל אם נמקם אותו בתחתית הוא יתפוס את כל השגיאות.

See the Pen FETCH error example by Ran Bar-Zik (@barzik) on CodePen.

אפשרויות

בכל הדוגמאות עד כה הראיתי אובייקט אפשרויות ריק, אבל אפשר לשנות אותו. הנה למשל בקשת POST שאני מעביר ל-mock API שבעזרתו אני יכול לדמות בקשות POST:


const options = {
  method: 'POST',
  data: {
    title: 'foo',
    body: 'bar',
    userId: 1
  },
  credentials: 'include',
  headers: {}
};

fetch('http://jsonplaceholder.typicode.com/posts', options)
  .then((response) => {
    return response.json();
  })
  .then((jsonObject) => {
  console.log(jsonObject)
    document.write(`ID ${jsonObject.id} was created!`);
  })
  .catch((error) => {
    document.write(error);
  });

בעוד שהקריאה זהה למדי לקריאה ל-API של צ'אק נוריס, הדבר היחידי ששונה הוא היעד (כי אני שולח קריאה ל-API אחר) ואובייקט האפשרויות. שם פירטתי את ה-method שלי, במקרה הזה POST ואת המידע שאני שולח. יש שם גם אפשרות לשנות את ה-headers וגם את מדיניות משלוח העוגיות (ה-credentials למי שמכיר). לא חייבים לפרט את כל האפשרויות שיש לנו אלא לשנות רק את אלו שאנחנו רוצים לשנות. אם נשים למשל רק method באפשרויות זה יהיה גם מעולה. הנה הדוגמה החיה למי שרוצה לשחק.

See the Pen FETCH POST example by Ran Bar-Zik (@barzik) on CodePen.

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

פוסטים נוספים שכדאי לקרוא

למפתחי ובוני אתרי אינטרנט

מדריך לשאילתות יעילות ל Chat GPT

כל אחד יכול לשאול את GPT, אבל אם תרצו לשאול אותו שאלות על תכנות – יש כמה שיטות וטיפים ליעל את העבודה מולו.

פתרונות ומאמרים על פיתוח אינטרנט

רינדור של קליינט סייד עם SSR

הסבר קצר על SSR מול רינדור קלאסי ולא. לא תמיד זה טוב להשתמש בו. אין כדור כסף שיכול לפתור הכל.

עבודה בהיי טק

איך מראיינים סניורים?

השיטה שלי לבדיקת התאמה טכנית למתכנתות ולמתכנתים בכירים עם כמה שנות ניסיון.

פתרונות ומאמרים על פיתוח אינטרנט

SSG עם next

אחרי שלמדנו במאמר הקודם מה זה SSR והבנו שלא מדובר בקליע כסף שפותר את כל הבעיות שלנו, נלמד על SSG שיכול להקל על כמה מהבעיות של SSR.

גלילה לראש העמוד