קריאת JSON באמצעות jQuery
הקדמה
Json הוא פורמט נוח לייצוג מבני אינפורמציה פשוטים ומערכים אסוציאטיביים. הפורמט הזה שימושי מאוד להעברת נתונים על הרשת בין שרת לאפליקצית רשת. דוגמא לסינטקס שצפוי בפורמט הזה , ניתן לראות ברשומה הבאה:
{
"Bussiness_Name": "Flora",
"Bussiness_Type" : "Sales",
"Bussiness_Address" :
{
"streetAddress": "Amnon VeTamar 31",
"city" : "Tivon",
"state" : "Israel",
"postalCode" : "22342"
}
}
מאמר הזה ידגים כיצד ניתן לקרא נתונים שהועברו בjson באמצעות jQuery. ישנם הרבה web services ברשת, שמציעים חינם מידע בפורמט json. עשיתי שימוש באחד מהם שמביא תחזית מזג אויר לימים הקרובים. השירות ניתן באתר: worldweatheronline.com
ואת צורת המידע שצפוי חזרה אפשר לראות ע"י משחק עם הממשק הבא: http://www.worldweatheronline.com/feed-generater.aspx
מה שנדרש מאדם שמעוניין בשירות הוא הרשמה קצרה שלאחריה תישלח לו למייל מחרוזת ייחודית אליה אתיחס בתור Api key ואותה יש לספק כאשר שולחים request לשירות הנ"ל.
האפליקציה המודגמת תציג תחילה דף עם כפתור. בלחיצת הכפתור האפליקציה תייבא את האיפורמציה של מזג האויר לחמשת הימים הקרובים ב-ajax ותציג אותה בטבלה.
האפליקציה מורכבת משני קבצים:
- weather_form.html – החלק ה html י שבו יוצג הכפתור וטבלת הנתונים
- ajax_call.js – קוד jquery שעיקרו לייבא את המידע ולכתוב אותו לטבלה.
weather_form.html:
תחילה בתוך ה-head מבצעים שני דברים:
- מכלילים את ספרית jQuery בגרסתה האחרונה
- מכלילים את קובץ ה-jQuery שאנו נכתוב על מנת ליבא את המידע ב-json
<!doctype html>
<html>
<head>
<script type="text/javascript" src="http://code.jquery.com/jquery-latest.js"></script>
<script type="text/javascript" src="ajax_call.js"></script>
</head>
בתוך ה-body מציבים כפתור ומסמנים אותו ב-id trigger, כזכור לחיצה על כפתור זה אמורה לשגר request ב-ajax אל ה-webservice של worldweatheronline.
בנוסף, נבנה כבר את הטבלה שתכיל את נתוני מזג האויר. הטבלה תסומן ב-"id="result, ותחילה תקבל את display:none כדי שכל עוד לא קיימים נתונים היא לא תוצג. הטבלה כבר מכילה את שורת הכותרות ובקשת ה-ajax שתשלח תביא את הנתונים לתוך גוף הטבלה.
<!doctype html>
<html>
<head>
<title></title>
<script type="text/javascript" src="http://code.jquery.com/jquery-latest.js"></script>
<script type="text/javascript" src="ajax_call.js"></script>
</head>
<body>
<button id="trigger">Press</button>
<br />
<table id="result" style="display:none">
<tr id="titles">
<th>Icon</th>
<th>Date</th>
<th>Max Temp (celzius)</th>
<th>Min Temp (celzius)</th>
<th>Wind Speed (km/hour)</th>
<th>Wind Direction</th>
</tr>
</table>
</body>
</html>
ajax_call.js
תחילה בתוך ה-click handler של הכפתור #trigger, אנו קוראים לפונקציה getJSON על מנת להביא את המידע.
$(document).ready( function ()
{
$('#trigger').click( function ()
{
$.getJSON("http://free.worldweatheronline.com/feed/weather.ashx?callback=?",
{
"q": "Toronto,Canada",
"num_of_days":5,
"format":"json",
"key":"your_api_key"
},
jsonParser
); // end of getJSON
}); // end of click
}); // end of document.ready
כמה מילים על getJSON:
זוהי פונקציה שיודעת להביא אינפורמציה בפורמט json תוך שימוש ב-Http Get Request.
הפרמרטרים הדרושים לה באופן כללי הם:
- url – הכתובת אליה תשלח ה-request.
- data – אובייקט (או מחרוזת) שמכיל נתונים הנדרשים לסקריפט המורץ על השרת.
- success – פונקצית callback שנקראת כאשר ה request מצליח. הפונקציה הזו מקבלת את האינפורמציה שחזרה מהשרת כשהיא כבר בצורה של אוביקט javascript.
בדוגמא שלנו:
ה-url מכיל את כתובת ה-web service שהיא: http://free.worldweatheronline.com/feed/weather.ashx ואליה שורשרה המחרוזת: callback=?
הדבר הזה נעשה על מנת לעקוף את מגבלת האבטחה שדפדפנים אוכפים שידועה בשם same origin policy. בקצרה, זוהי מגבלת אבטחה שלפיה כל בקשת ajax שנעשית ע"י עמוד רשת יכולה לבקש מידע מאותו domain ממנו יצאה הבקשה. במקרה שמבקשים מידע מ-webservice חיצוני, אנו כמובן מתנגשים עם המגבלה הזו. jsonp זה מנגנון שפותח על מנת להתמודד עם ההתנגשות הזו וכאשר ה-url מכיל את המחרוזת callback=?, ה-request יטופל כ-request של jsonp. אפשר לקרא על זה יותר בהרחבה כאן: http://www.codeproject.com/Articles/42641/JSON-to-JSONP-Bypass-Same-Origin-Policy
ה-data אצלנו הוא אובייקט שמכיל נתונים הנדרשים ל-webservice לגבי אופן אספקת המידע.
q – מכיל את העיר והמדינה עליה רוצים את האינפומציה.
num_of_days – מספר הימים עליהם נרצה דיווח.
format – באיזה פורמט תוחזר האינפורמציה, הwebservice הזה יודע גם להחזיר xml ועוד. במקרה שלנו כמובן נרצה json.
key – זוהי המחרוזת הייחודית שסופקה לנו בעת ההרשמה, אותה הזכרתי בהקדמה למאמר.
success – פונקצית ה-callback שנקראת במקרה של הצלחה אצלנו תיקרא jsonParser ועליה ארחיב בסעיף הבא. פונקצית ה success מקבלת פרמטר שהוא בעצם כבר אובייקט javascript שמייצג את מבנה ה-json שקבלנו מה-web service. לדוגמא, ה-json שצפוי לנו כאן הוא משהו כמו:
{"data":
{
"current_condition": [ {"cloudcover": "0", …. } ],
"request": [ {"query": "Toronto, Canada", … } ],
"weather": [
{"date": "2012-04-19", … },
{"date": "2012-04-20", ….}
]
}
}
ובהתאם, אנו מקבלים אוביhקט javascript עם מבנה זהה. לדוגמא:
קיבלנו אובייקט עם שדה בודד data. השדה data הוא אוביקט בפני עצמו וכשפורשים אותו רואים משהו כזה :
את ה-screenshot הנ"ל יצרתי עם הפקודה console.log(info); מתוך הפונקציה jsonParser. זו פקודה שבאמצעותה בתוך ה-Firebug רואים את המבנה של הפרמטר info. רואים שכמו במבנה ה-json, יש לנו אובייקט עם שדה ראשון data. בתוך האובייקט data ישנם השדות current_condition, request ו-weather כאשר weather מכיל מערך עם 5 תאים. כל אחד מהתאים גם הוא אובייקט שאת המבנה המדויק שלו אפשר לראות בתא האחרון 4. למעשה השדות current_condition ו-request אינם מעניינים את האפליקציה שלנו, והיא מחפשת רק את השדה weather שמכיל תחזית ל-5 הימים הקרובים.
הפונקציה jsonParser:
function jsonParser(info) {
var content = '';
$.each(info.data, function(ind,record)
{
if (ind=="weather")
{
$.each(record , function(key,weather_obj)
{
content += '<tr>';
content +='<td><img src="' + weather_obj.weatherIconUrl[0].value + '"/></td>';
content += '<td>' + weather_obj.date+'</td>';
content += '<td>' + weather_obj.tempMaxC+'</td>';
content += '<td>' + weather_obj.tempMinC+'</td>';
content += '<td>' + weather_obj.windspeedKmph+'</td>';
content += '<td>' + weather_obj.winddirection+'</td>';
content += '</tr>' +"\n";
});
}
});
$('#titles').after(content);
$('#result').show();
}
תחילה מגדירים משתנה content . המשתנה הזה מיועד להכיל את האינפורמציה שהוחזרה עטופה ב html המתאים , במקרה שלנו – שורות של טבלה.
הלאה, על כל אחת מרשומות המידע שהוחזרו עוברים באמצעות $.each. בדוגמא שלנו המידע החוזר מכיל רשומה שנגישה דרך המפתח request , רשומה נוספת current_condition ורשומה שנגישה דרך המפתח weather. לכן, ישנו ה if(ind=="weather") לוודא שאנו נמצאים ברשומת weather.
על הדיווחים בתוך רשומת weather אנו עוברים באמצעות $.each נוסף. כל weather_obj הוא למעשה אוביקט שמתאר את מזג האויר של תאריך ספיציפי. הkey כאן מכיל אינדקס מספרי (0, 1 , 2 וכו).
בתוך ה $.each-הפנימי ביותר , אנו בונים את שורת המידע. כל שדה בתוך ה weather_obj מושם בתוך תג td , כאשר המשתנה content אוסף לתוכו את כל שורות הטבלה. בתוך weather_obj כמו באוביקט, אנו ניגשים לכל שדה באמצעות נקודה. לדוגמא השדה טמפרטורה מקסימלית נגיש דרך weather_obj.tempMaxC. יש לנו חריג אחד בין השדות של weather_obj והוא שדה התמונה : weatherIconUrl , שלמעשה הוא שדה מערך. חזרו לscreenshots כדי להיווכח בזה.
אפשר לראות אותו כמערך שבכל אחד מהתאים שלו עשוי להכיל אוביקט עם השדה value
כנראה שיתכנו מספר תמונות ,אני בחרתי להציג רק את הראשונה ולכן אנו ניגשים כך:
weather_obj.weatherIconUrl[0].value
לבסוף, אנו מצרפים את המידע שמוכל במשתנה content אחרי שורת הכותרות (titles) ודואגים לכך שהטבלה תוצג ע"י $('#result').show.
דוגמא ל-json שחוזר מהשירות אפשר לראות בקובץ json_output.txt.
על מנת להריץ את האפליקציה, הורד את הקובץ: weather.zip ובתוך ajax_call.js רשום בשורה 10 את -api key שקיבלת לאחר הרשמה לשירות.
תגובות בפייסבוק