אי אפשר לעזור לך.
מי שיכתוב לך במייל שהוא יכול לעזור, הוא נוכל.
ד' ימלא חסרונך.

dovid
-
המייל שלי נפרץ -
מדריך כתיבת אפליקציה וובית, Full-Stack, צעד אחר צעדשיעור 3, חזרה לקוד, רק הסברים
טרמינולוגיה קצרה בפרט למי שדילג על הפילוסופיה האחרונה:
בקשה request = ההודעה/מידע שהדפדפן שולח לאתר בעת כניסה לדף או בעת לחיצה על כפתור.
בקשה מכילה תמיד כתובת (מה שרואים בשורת הכתובת), כותרות כל שהם ואופציונלית תוכן נוסף בגוף בקשה (לא חשוב כעת להבין את השניים האחרונים).
תשובה, תגובה, response = ההודעה/המידע המידע שמגיע מהאתר לדפדפן כתגובה על בקשה (למשל דף אינטרנט רגיל או תמונה וכדומה).
שרת server = תוכנה שמגיבה לבקשות רשת האמורות ומחזירה תשובה. התוכנה הזו רצה על מחשב שלרוב מכונה גם שרת, למרות שזה "בניין" רב דירות שבו יכול להיות "שרת" אחד או יותר.
חיבור, שיחה, קונקשיין, connection = ערוץ תקשורת בין הדפדפן לאתר, שקול לשיחת טלפון בין שני אנשים. נפתח עם תחילת הבקשה ומסתיים עם סיום התשובה.שורה 1
const http = require('http');
ייבוא מודול (מילה נרדפת לספריה, חבילה) מובנה של נוד בשם http. מודול זה מכיל המון כלים עבור תקשורת בפרוטוקול http.
הייבוא תמיד מחזיר ערך, במקרה שלנו אובייקט רב מימדים שאנו מציבים אותו במשתנה (לא בדיוק משתנה אלא קבוע, זה לא קריטי להבין כעת), למשתנה קראנו גם http.שורה 3-6
היא פונקציה JS שלא עושה "בינתיים" כלום, נחזור אליה להלן.
שורה 8
var server = http.createServer(handleAllRequest);
קריאה לפונקציה createServer שבמודול http.
בא נתמקד בפונקציה. שמה createServer כלומר "צור שרת". הסברנו בחלק התיאורטי ששרת הנה תוכנה שמתפקדת על תקן "מלצר", מקבלת בקשות רשת (קרי למשל כתובות של דפי אינטרנט של האתר שלנו) ומגיבה עליהם.
כשאנו רוצים ליצור שרת, אנחנו רוצים להחליט מה תהיה התגובה לכל בקשה (למשל לענות שלום עולם).
אנו רוצים לומר לשרת הזה שאנחנו יוצרים מה הוא צריך "לענות" כתגובה לכל סוג של כתובת/בקשה.
לשם כך הפונקציה הזו מקבלת פרמטר שנקרא לעיתים קרובות קאלבק-callback.
לשם הפשטות ניתן להתייחס לקלאבק בשפת JS, כאירוע.
אירוע זה כמו בhtml שיש כפתור עם התכונה onclick שמשמעותו "לכשהכפתור יילחץ עשה כך" כך כל אירוע בשפות תכנות זה הקוד או הפקודה שיש לעשות לכשייקרה משהו שהתזמון שלו מתבצע ע"י חלק חיצוני לקוד שלנו.
כך במקרה שלנו אנו מספקים לcreateServer בסוגריים פרמטר שהוא פונקציה שהשרת יפעיל כל פעם שהוא יקבל בקשה (אפשר לכתוב ישירות את הפונקציה בתוך הסוגריים, אנו כתבנו את שמה של הפונקציה - זה אותו הדבר).השרת האמור לא יפעיל את הפונקציה סתם ככה:
handleAllRequest()
אלא הוא יספק לה בסוגריים פרמטרים נחוצים שנידע מי ביקש מה ואיך לענות לו ישירות. הפרמטר הראשון הוא request (מייצג את כל פרטי הבקשה) השני response (מייצג את כל פרטי התשובה העתידה, ואת הפעולות שניתן לבצע עליה, שהרי היא עוד לא נשלחה).הפונקציה מחזירה מופע (מה זה מופע, ומה זה אובייקט? לא דחוף כעת להבין, תמיד אפשר ומומלץ לשאול!) של אובייקט מסוג server שמייצג את ה"שרת", את המופע הזה אנו שמים בתוך משתנה בשם server.
כעת השרת מכובה, צריך להפעיל אותו, ויש לכך פונקציה בשם listen, פה נעבור לשורה 9:server.listen(3000);
פה אנו משתמשים במופע השרת שיצרנו, ומפעילים בו פונקציה בשם listen = תתחיל להאזין - לתת שירות (כלומר להפעיל בכל בקשה את הפונקציה handleAllRequest שסיפקנו בעת יצירתו) לכל מי שפונה אליך מעתה ואילך, עם פרמטר 3000 של מספר הפורט.
כשנוד (יוסבר בהמשך מה זה) מריץ את הקוד שלנו ומגיע לשורה זו, הוא פונה למערכת ההפעלה, ומבקש ממנה לנתב אליו (ורק אליו) את הבקשות שפונות לפורט 3000 שיתקבלו בכלל כרטיסי הרשת של המחשב פעולה זו מחייבת הרשאות ניהול (וגם בפעם הראשונה זה מאושר רק אחרי שנאשר הודעה על כך).
מערכת ההפעלה בודקת האם כבר הפורט הזה התבקש ע"י תוכנית שרצה כעת, ואם כן היא תדחה את הבקשה, הפונקציה תעורר שגיאה והתהליך יפול ויהיה כתוב בהודעות אדומות למטה את הודעת השגיאה. בחרנו את פורט 3000 כי הוא לא בשימוש שכיח וממילא הוא כנראה פנוי. תוכלו לנסות את פורט 80, אם לא תקרה שגיאה תוכלו לגשת בדפדפן לדף עם http:/localhost ללא הנקודתיים 3000, שכן סתם http הוא בחזקת 80 אז שאומרים אחרת.שורה 3-6, הפונקציה handleAllRequest.
function handleAllRequest(req, res) { res.write('Hello World'); res.end(); }
הפונקציה הזו היא השחקן הראשי בקוד שלנו. בגלל ששמה סופק כפרמטר לcreateServer היא תרוץ כל פעם שתהיה בקשה (כל ריענון של הדף).
צריך להבין שכלל הקוד שכתבנו רץ פעם אחת מייד עם הפעלתו ע"י נוד או ע"י F5 כפי שעשינו. הוא מבוצע מיידית, אחת ולתמיד. אבל הפונקציה הזו היא בדיוק להיפך, היא לא רצה מייד, אלא כל פעם שיש בקשה, הsever מריץ אותה והיא מתבצעת.
בא נעבור עליה: יש בה מבנה פונקציה רגיל, שם (איזה שבא לנו), שתי פרמטרים (עם שמות איזה שבא לנו כבל פונקציה). בגוף הפונקציה יש שני שורות שניהם עושים שימוש באובייקט res שמייצג את הresponse, הוא סופק לנו על ידי אותו אחד שהפעיל את הפונקציה בבוא בעת של הבקשה, הלא הוא יקרינו השרת.
השורה הראשונה כותבת לתשובה, מלל, השניה פוקדת על סיום הבקשה, סגירת ה"שיחה".בהודעה הבאה נוסיף טיפה דינמיות (=היפך מסטטי, סטטי = מצב בלתי משתנה, תמיד התשובה היא זהה - hello world)
לקוד שלנו. -
מדריך כתיבת אפליקציה וובית, Full-Stack, צעד אחר צעדשיעור 1, helo world!
א. ניצור תיקיה במחשב (אנגלית, ושלא יהיה רווחים בשם).
ב. נפתח את התוכנה Visual Studio Code.
ג. נלחץ על הלינק Open Folder או דרך התפריט File ואז Open Folder...
ד. בתיבת הדו שיח ננווט לתיקיה שיצרנו ונלחץ על Select Folderכעת אנחנו עם סביבת עבודה - תיקיה, ללא קבצים.
בצד שמאל יש (נכון לכתיבת המדריך) חמש אייקונים גדולים, הראשון הוא להראות את חלונית הסיור ב"פרוייקט" שלנו.
החלונית מחולקת לשני מקטעים, העליון (OPEN EDITORS) מראה את כל חלוניות העריכה הפתוחים כעת, והתחתון מראה את עץ הקבצים שנמצאים בתיקיה.
בריחוף על כותרת המקטע התחתון מופיעים כמה אייקונים שימושיים, מוקפים בצהוב חלש בתמונה:הסמלים האלה הם לחצנים לפעולות על הקבצים: ריענון, תיקיה חדשה, קובץ חדש.
ו. נלחץ על הלחצן של קובץ חדש (אפשר גם קליק ימני בחלל החלונית הזו ואז New File),
ז. נקרא לקובץ app.js, לחיצה על אנטר תשמור את השם ותפתח את הקובץ.
ח. נכתוב בקובץ את הקוד הבא:const http = require('http'); function handleAllRequest(req, res) { res.write('Hello World'); res.end(); } var server = http.createServer(handleAllRequest); server.listen(3000);
ט. כעת נלחץ F5 במקלדת, או נלחץ על הסמל הצידי הרביעי (סוג של חיפושית שמסמלת את ה"באג") ואז ללחוץ על הכפתור Debug With Node.js.
י. נפנה לדפדפן, ונכתוב שמה בשורת הכתובת http://localhost:3000 ואנטר (או אפשר ללחוץ על הלינק פה...), נראה את המילים hello world.
עקרונית גמרנו כעת להקים "שירות אינטרנט דינמי".
בפוסטים הבאים אנתח את המשמעות של הקוד ואת המשמעות של התוצאה שלו צעד צעד.
שאלות? בשמחה! בפורום! תודה רבה שהייתם איתנו.
(נ.ב. המדריך מייגע למי שקצת יודע, אבל ככה הוא לא עושה שום הנחות בהסברים. אתכם הסליחה). -
Regex - ביטויים רגולרייםביטוי רגולרי, שזה באנגלית Regular Expression זה בעצם פרוטוקול של שפה לתיאור טקסט רצוי (חיפוש, החלפה, או בדיקה האם טקסט עומד בחוקים), ע"י סימנים מיוחדים שמבטאים כל מיני משמעויות גמישות לתוצאה המתבקשת.
במגוון גדול מאוד של תוכנות וכלי תוכנה, יש מקום לregex או לתת וריאציה שלה (כמו מקרים מצומצמים של תמיכה בגוקר *, ? שיש בשורת הפקודה בwindows או בוורד שיש סט רחב יותר תחת השם תווים כלליים, מי שמכיר את אינדיזיין פגש שם את גרפ (שהשם הוא לקוח מכלי נפוץ במערכות לינוקס לעבודה עם רג'קס), ניתן אפילו להצביע על תוכנות כמו פרויקט השו"ת של בר אילן ובני משפחתו שבעצם תומכים בחיפוש בשפה שהם יצרו לעצמם אבל היא בעצם עושה את אותו רעיון שזה תיאור של טקסט רצוי בצורה די מתמטית).
הרעיון הוא די פשוט, הסיטואציה: המתכנת כבר כתב קוד לחיפוש עבור המשתמש. אבל המשתמש עוד לא אמר למתכנת בעת כתיבת הקוד מה לחפש... אז כמובן המתכנת השאיר לו לבחור מה לחפש. הבעיה שהמשתמש לפעמים גם לא יודע מה הוא מחפש, אבל רק יש לו כללים מאוד ברורים לגבי התוצאה "אני רוצה מילה בת שלושה תוים שמתחילה בא", או "אני רוצה למצוא מספר טלפון". אז המתכנת הכין סט של אפשרויות טקסטואליות שמבטאות כללים פשוטים של מתחיל ב, נגמר ב, מורכב מטווח ו... ההמשך בregex. העובדה שבסופו של דבר כל חיפוש על טקסט מגיע בסוף לאותם אפשרויות אז יצרו שפה די מוסכמת (עם שינויים קטנים ספציפיים לכל מימוש), וממילא גם יצרו ספריות שגם "מבינות" וגם "מבצעות", כלומר המתכנת בדוגמה שלנו לא ימציא את הגלגל מחדש אלא סה"כ ישתמש עם כלי מוכן לאיתור טקסט בתוך טקסט ע"י שימוש בתווים הכלליים הללו.
מי שמכיר את שפת JS, שמה ממש קל לבדוק ולשחק עם regex שקיבל מקום מכובד בשפה, ואגב הפעולה שלו בשפה זו מהירה במיוחד (יותר מדוטנט למשל).
יש הרבה כלים לבדקה ונסיון של regex, חלקם אונליין, אני למשל משתמש על פי רוב באתר הזה: https://regex101.com/. בתיבת הטקסט העליונה כותבים את המחרוזת לחיפוש, ובחלק שתחתיה כותבים טקסט כל שהוא שעליו יתבצע החיפוש. בצד יש הסבר שלאט לאט יובן, שמנתח את הטקסט שהוזן בחיפוש. העברית לא הכי נתמכת טוב, עדף לצרכי טסטים לכתוב נטו באנגלית (ולעברת רק בסוף ב"הלכה למעשה").
אתר נוסף שלחלק מהאנשים עשוי להיות ידידותי יותר הוא http://regexstorm.net/tester, עוד אתר הוא https://www.regexpal.com/, יש כמובן עוד עם הבדלי טעם וריח.כמו"כ אפשר לבדוק בשפת JS, שיש לה סביבת עבודה בכל דפדפן בקונסול.
תפתחו את הקונסול של הדפדפן (F12 בכרום), שם בשביל נוחות הניסוי הכינו כל מחרוזת טקסט ארוכה בתוך משתנה, למשל:var text = 'יש הרבה כלים לבדקה ונסיון של regex, חלקם אונליין, אני למשל משתמש על פי רוב באתר הזה: https://regex101.com/. בתיבת הטקסט העליונה כותבים את המחרוזת לחיפוש, ובחלק שתחתיה כותבים טקסט כל שהוא שעליו יתבצע החיפוש. בצד יש הסבר שלאט לאט יובן, שמנתח את הטקסט שהוזן בחיפוש. העברית לא הכי נתמכת טוב, עדף לצרכי טסטים לכתוב נטו באנגלית (ולעברת רק בסוף ב"הלכה למעשה"). כמו"כ אפשר לבדוק בשפת JS, שיש ל סביבת עבודה בכל דפדפן בקונסול. תפתחו את הקונסול של הדפדפן (F12 בכרום), שם כתבו קודם כל מחרוזת טקסט ארוכה בתוך משתנה, למשל:'
הקישו אנטר אחרי הפקודה.
כעת תוכלו לחפש ולהחליף בטקסט הזה ע"י regex, למשל (כל שורה היא דוגמה עצמאית):/א/.exec(text) /א/.test(text) text.replace(/א/ , "A") text.split(/א/)
(הא המוקפת בתוי הסלש (לוכסן), מהוה את הביטוי הרגולרי. במקרה שלי זה א. כל תווים מוקפים בלוכסנים בJS הופכים למופע של מחלקת RegExp, אני ידבר על כך בלי נדר בהמשך).
אגב, מי שלא מבין כלום בשורות האלה זה אומר שהוא לא מכיר את regex ו/או את JS ואין בכך שום עיכוב לגבי הבנת הנושא הנוכחי. הבאתי את כל זה כדוגמה למקום בו ניתן לשחק עם הביטויים.כמו"כ יש תוכנות שהחיפוש וההחלפה בהם תומכים בregex ממש אורגינל כמו למשל notepad++, או visual studio code ובעצם כל עורך קוד/טקסט מתקדם וק"ו IDE, מי שרוצה יכול לשחק שמה לשם לימוד השפה.
לסיום ההקדמה עוד משהו, אני לא יודע regex וכנראה גם אתם לא תדעו את השפה על בוריה, ולדעתי זה סימן על בריאות נפשית :). יש את הליבה השימושית והשאר מחפשים באינטרנט כשצריכים או שואלים את החברים או בפורום...
בפוסט הבא הקדמה מעשית + פרק ראשון.
-
API נדרים פלוס, נחסם?@Nedarim מנסיוני, הדרך הטובה ביותר למנוע ממפתחים לעשות קומבינות זה לתת להם דרך נורמטיבית כל שהיא.
אם יהיה API (אפילו בהגבלות כל שהם ו/או בתשלום), וכפי שאמרו לא בהכרח לסליקה אלא אפילו סתם לחייב הו"ק וכדומה, זה גם יעזור מאוד למפתחים רבים וגם יוריד מהוריד שלכם את כל המתחכמים.
ברור שלהחזיק API זה עוד בלגן ותחזוקה, אבל נראה לי שהעדר של זה יכול להוליד הרבה כאבי ראש. -
מדריך כתיבת אפליקציה וובית, Full-Stack, צעד אחר צעדשיעור 5
תקציר: אנו באמצע לכתוב אתר "משוכלל" בו יוכלו להוסיף פריט לרשימה ולצפות כמובן ברשימה.
החלטנו על שני כתובות, אחת להוספת פריט, ואחת לרשימה כולה. בדקנו איך אנו יכולים לדעת בתוך הפונקציה את ה"פרט" הזה שנקרא כתובת, ומצאנו אותו כמאפיין url בפרמטר req. כיון שכן נתחיל בבניית שלד לקוד האתר:const http = require('http'); var list = []; function handleAllRequest(req, res) { if (req.url == '/') res.write('Hello To List Page!'); else if (req.url == '/add-item') res.write('Hello To Item-Add Page!'); else res.write('Opss... Not Found!'); res.end(); } var server = http.createServer(handleAllRequest); server.listen(3000);
הכרזנו פה בשורה 3 על משתנה בשם list ושמנו בו מערך ריק. בו יהיו הפריטים של הרשימה.
להזכיר, נוד מריץ את הקוד פעם אחת בלבד. הפוקנציה handleAllRequest יוצאת דופן כי אותה ביקשנו להריץ לכשתהיה בקשה, וליתר דיוק כל פעם שתהיה. לכן, המשתנה list בעצם מוכרז ומאוכלס במערך ריק פעם אחת, אבל הוא נגיש מתוך הפוקנציה handleAllRequest לאורך כל חיי האתר.בשורות 6-11 אנו בודקים את ערכו של המאפיין url ופועלים בהתאם (אחד לשורש האתר, add-item יביא לדף יכיל טופס להוספת ערך, וכל כתובת אחרת תיתקל בסוג של 404...). בינתיים זה רק שלד, בהמשך נצטרך לעשות יותר בכל מצב.
קצת html וגם על content-type וכותרות (headers)
בשביל שצד הלקוח יתקשר עם צד השרת, אנו חייבים טופס בו ניתן לרשום ערך, וכפתור שליחה יפה.
בשביל זה אנו צריכים לעבוד עם HTML ולא עם טקסטים כמו שעשינו עד עכשיו.
בשביל לשלוח ללקוח HTML לא די לשנות את הטקסט לHTML אלא יש להסביר לדפדפן שהתוכן הוא HTML, עושים את זה באמצעות כותרת בשם content-type (דיברנו על כותרות קצת בעבר, ונייחד לזה שוב דיבור כשנגיע למושג עוגיות שם נרחיב, כך שכעת אפשר לחפף). וזה אומר שנכתוב בפונקציה שלנו כזה קוד:function handleAllRequest(req, res) { res.setHeader('Content-Type', 'text/html'); if (req.url == '/') res.write('Hello To List Page!'); else if (req.url == '/add-item') res.write(`<form> Enter the item value: <input type="text" name="the-name" > <br> <input type="submit" > </form>`); else res.write('Opss... Not Found!'); res.end(); }
בלגן. ובכן,
בשורה 2 אנו מגדירים (דרך הפרמטר res שמייצג את אובייקט התשובה) כותרת באובייקט התשובה. בגלל פונקציה זו תתנוסס במכתב-התשובה שלנו השורה content-type: text/html דבר שישפיע מאוד על יחס הדפדפן לתוכן - הוא לא יציג תגיות, אלא טקסט מובנה/מעוצב בהתאם לתגיות.
בשורות 6-11 השתמשנו עם טילדה (התו הזה: `) כדי לעשות מחרוזת טקסט מרובת שורות, בה כתבנו טופס HTML צנוע (ובלתי חוקי, כי הרי מסמך HTML יש לו כללי פתיחה והמינימום שלו ארוך בהרבה! אבל כל עוד הדפדפן מגלה יחס סובלני, וזה טוב ללימוד דוגמה קומפקטית, אז למי אכפת?). מייד נדון על תוכנו של הטופס שכתבנו.
תריצו ותיכנסו לכתובת http://localhost:3000/add-item ותראו את הטופס הHTML היפה שיצרנו.HTML, הקדמת רשות (קצרה ולא מסבירה, רק ריענון. להרחבה אנא שאלו בפורום):
HTML הוא פורמט/תחביר כתיבה שכולל תגיות (הסוגריים הזויותיות הללו <>), תכונות (מפתח ערך, בסגנון הזהאני="אתה"
) וערכים (התוכן שבין צמתי התגיות והערכים של התכונות.
זה קובץ טקסט עלוב, ככל טקסט אחר, אלא שהדפדפן קורא אותו ואינו מציג אותו כפי שהוא, אלא אחרי "הבנה" של המוסכמות על התגיות והתכונות והערכים שבהם.
הוא נוצר בראשית ימי האינטרנט להצגת מסמכים. מסמך טקסט רגיל הוא "שטוח" חסר מבנה ויכולת לעצבו.
לעמות זאת מסמך HTML מאפשר להגידר היררכיה וחלקים במסמך, לתאר אותם הן ע"י שמות התגיות והן ע"י התכונות וגם ע"י מיקומם בהיררכיה של התגיות. בהתחלה השתמשו חזק מאוד בHTML כדי לעצב ישירות את מראה המסמך הסופי, אך מאוחר יותר הבינו שלא חכם לערבב חזות עם מבנה, וכיום מאוד משתדלים שHTML ישמש נטו לעיצוב מבני (כמו כותרת, קטע, כפתור וכו'), ולא לצרכי עיצוב (כמו טקסט אדום).
בראשית ימי האינטרנט שרת היה יודע תמיד למפות נתיב של בקשה לקבוץ הנכון וככה להגיש קבצים סטטייים- בלתי משתנים. בהמשך התפתחות האינטרנט התחילו לפתח שרתים דינמיים שהגיבו לבקשות חיפוש למשל, וייצרו דף HTML שהכיל תוצאות מחיפוש שבוצע בצד השרת. בשביל זה הכניסו בפרומט הHTML תגיות ותכונות מיוחדות שאפשר להכליל אותם בכותרת "טפסים". ועל כך בקטע הבא. סיום ההקדמה.טפסי HTML, ומתודות HTTP
טפסי HTML הם מכלול התגיות והתכונות שרלוונטיות ליצירת אינטראקציה בין הדף לבין השרת.
האלמנט הראשי של טפסי HTML הוא התגית Form. היא נדרשת תמיד בטופס HTML, וכל הקלט של המשתמש צריך להיות "עטוף" בה.
אלמנט שני וכמעט אחרון זה הinput. זה אלמנט שבו המשתמש יכול להזין/לפעול ערך/פעולה שהטופס ישלח לצד השרת. יש המון סוגים של input שנקבעים לפי הtype, כמו text, number email וכו'. יש סוג שנקרא submit שהוא סוג שמוצג ככפתור "שליחה". לחיצה עליו בטופס תשלח את הטופס על ערכיו לצד השרת.מאי משמע "תשלח"? בדואר אויר? איך, ולאיפה?
ובכן הערכים יישלחו בבקשת אינטרנט, שאנו לא מפסיקים לדבר עליה.
נחזור לבקשת אינטרנט:
השורה הראשונה של בקשת כניסה לדף http://localhost:3000/add-item נראית ככה:GET /add-item HTTP/1.1
המילה GET היא המתודה, אחת מכמה מתודות שיש בפרוטוקול HTTP. מתודה אחרת שמעניינת אותנו כעת היא POST.
בקצרה נאמר בGET זה בקשה "ריקה", כמו כל הזנת כתובת בדפדפן ואנטר, וPOST זה בקשה "מלאה, אפשר לשים בה תוכן מעבר לכתובת ולכותרות (התוכן נמצא אחרי הכותרות - מה שמבדיל ביניהם זו שורה ריקה).עוד הבדל חושב: מתודת GET נועדה עבור בקשות "קריאה בלבד" כלומר בקשות שלא נועדו לעשות שינוי כל שהוא בעולם. למשל בקשת רשימת ערכים זו בקשת קריאה. בקשת הוספה מחיקה ועדכן הם בקשות שמבקשות לעשות שינוי, ואמורים שלא להתשמש במתודה GET עבורם (אין לכם במועדפים כתובת שלחיצה עליה שולחת מייל למשל, נכון?).
למרות שהמתודה GET לא עשויה לשלוח נתונים של ממש, אבל אי אלו פרמטרים לבקשה. במתודת GET הדרך להעביר אותם היא בquery, אותו חלק אפשרי של הURL שפעם סיפרנו עליו שמתחיל בסימן השאלה, עד לסופוף הכתובת (או לסולמית אם ישנה)
נחזור לטופס שלנו, הוא נראה ככה:
<form> Enter the item value: <input type="text" name="the-name" > <br> <input type="submit" > </form>
תגית הטופס (form), היא המפתח לפעולה של הדפדפן בעת השליחה.
בטופס הזה יש רק שני רכיבי קלט משתמש, אחת לטקסט ואחת לכפתור השליחה. לכפתור הטקסט יש תכונה (attribute) שנקראת name שעשויה להצמדה על הערך שהמשתמש יכניס, שנדע תחת איזה שדה בטופס הוא הוזן (שהרי יכולים להיות כמה וכמה שדות).
באלמנט הform יש שני תכונות אופציונליות (=בלתי נדרשות לפעולה תקינה) אחת בשם action והשניה בשם method.
action קובע לאיזה כתובת הדפדפן ישלח את הבקשה ובהתאם יקבע את הכתוב בשורת הכתובת.
במידה והactio לא קיים, הברירת מחדל היא הכתובת הנוכחית. זה מה שיקרה אצלנו.
method קובע באיזה מתודת HTTP תהיה הבקשה, GET או POST. אם שולחים בPOST הערכים יהיו ב"מכתב" הבקשה, אחרי שורה ריקה שאחרי הכותרות. במקרה של GET הנתונים יישלחו בכתובת עצמה, אחרי סימן שאלה להפרדה בין הכתובת לנתונים.
בשני המקרים, הנתונים יעוצבו בפומט כזה שם=ערך&שם-אחר-ערך&שם-נוסף=ערך.
תוכלו לנסות לשים ערך בטופס שלנו בכתובת http://localhost:3000/add-item ולצפות בכתובת שהדפדפן הוביל אליה. התשובה שמתקבלת היא לא מעניינת (אנו מקבלים Opss... Not Found! כי לא תכנוו אפשרות של כתובת עם סימן שאלה אחרי הadd-item).המתודה GET לא מתאימה עבורינו, כי אנו הולכים לעשות שינויים בצד שרת, לכן בא נכתוב בטופס ככה:
res.write(`<form method="POST"> Enter the item value: <input type="text" name="the-name" > <br> <input type="submit" > </form>`);
שינינו פה רק שתי מילים, שהוספנו את התכונה
method="POST"
לאלמנט הטופס.
כעת נריץ שוב (בעת הרצה בVSCODE יש סרגל צף של אפשרות הפסקת ההרצה, ויש גם כפתור להתחיל מחדש, שימושי!) וניכנס לכתובת http://localhost:3000/add-item נכניס ערך ולחץ על ה"שלח", לא יקרה משהו מיוחד, אבל עשינו כל מה שדרוש בצד לקוח!בשיעור הבא נדבר על טיפול בטפסי HTML בצד שרת.
כמו"כ נראה לי שנעביר את הקוד של הHTML לקבצים בפני עצמם. -
קבוצת התכנות הסגורההחלטתי לשקול בכובד ראש את מהות ואופן הקיום של הקבוצה הסגורה.
בינתיים אני אהפוך אותה ללא זמינה כדי שנוכל לארגן אותה מחדש אם יידרש ו/או לשקול פרמטרי צירוף חדשים וכדומה.
התחליף לבינתיים יהיה פורום תכנות הרגיל שהולך ומתעשר לאחרונה בחברים ובהודעות איכות.
אם יש למישהו בעיה מסויימת או מידע מסויים שהוא נזקק לו משמה, אפשר לשלוח לי למייל בקשה מנומקת ואשתדל להנגיש את הדרוש.עמכם הסליחה,
דוד. -
תכנות | איך להתחיל?@למה אמר בתכנות | איך להתחיל?:
אני מאוד רוצה לעזור לך, אבל בשביל לעזור לך אתה צריך להסכים להיות אמיתי ושקוף ולא לפחד על התדמית שלך.
יש מי שמפחד ולא מעיז להיות אמיתי, ובגלל זה יכתוב שהוא יודע יותר ממה שהוא יודע כי הוא חושש שאם הוא יחשוף מה הוא לא יודע, לא יביטו לעברו.
יש מקרים הפוכים שנראה לי אתה שמה: מפחד של ציפיות או מוסר על ידע חלקי אתה בוחר להמעיט בערך עצמך כדי שלא יבנו עליך בגרם:אני מדבר על בן-אדם (אני...) שאין לו ידע בכלווום
כלום פירושו לא מחשבים לא טכנולוגיה ממש כלוםלא. יש לו ידע בכמה דברים רק שהוא מעדיף שלא יצפו ממנו להרבה.
אז תספר לנו מה אתה יודע למחצה לשליש ולרביע, ואני מבטיח לא להלקות בך מוסר ותוכחה.
(הידע ה"מועט" שלך גם חשוב להבין מה התפיסה שלך לגבי תכנות ולמה החלטת שאתה רוצה לתכנת ולא להיות נהג הובלות). -
תרופה לקרונה או עוד משועמם?האשכול כולו עבירה על החוק, אבל אף אחד לא גילה את אוזני.
בלי קשר אם זה נכון או לא, גם אם המצווה הכי חשובה לדעתכם זה להפיץ איזה בשורה מצילת חיים, אין רשות לעשות את זה בפלטפורמה הזו גם לא בדרל של דיון וכדומה. מבחינתי כל מה שהגיע במייל בחזקת שטויות עד שיוודע לי על מקרה אחד בהיסטוריה של משהו טוב שהגיע לעולם במייל מתגלגל. -
ערוץ הטלגרם של המוזיקה החרדיתבכללים המעטים שיש למרחב הפרטי, יש כלל:
ה. כשר: וודאו שהתוכן מאה אחוז כשר לעיניים חרדיות, כל קישור, וידאו או תמונה חובה לוודא שהוא פתוחים בנטפרי אחרי בדיקה.
-
עדכונים לחוקי הפורוםכל פעם שחוקי הפורום יתעדכנו נציין פה את השינוי, ונפרסם את הנושא ליידע את באי האתר.
עדכון אחרון: 17/05/2020
העדכון:פרסום מקביל: אין לפתוח נושא בתחומים על נושא שנפתח על ידי אותו כותב (או מי מטעמו) בפורום/אתר אחר במקביל, ולהיפך - אין לפתוח בפורומים אחרים נושא שנפתח פה, אלא אם כן מדובר בנושא של בקשת עזרה וכדומה ועברו שלושה ימים לפחות מהפרסום המקורי בהם לא התקבלה העזרה המבוקשת בנושא. נושאים קריטיים בזמן ובחשיבות כמו השבת אבידה לא בכלל הזה.
-
מדריך כתיבת אפליקציה וובית, Full-Stack, צעד אחר צעדשיעור 4, דינמיות
מעכשיו ואילך נתחיל לכתוב משהו אמיתי. קיבלנו נניח הזמנה לבנות אפליקציית ווב "מורכבת", - רשימה.
האפיון שקיבלנו:
א. אפשר להוסיף פריט לרשימה
ב. אפשר לראות את הרשימה
בשביל זה נשתמש בניתוב (בסיסי ופרימיטיבי) בו נבדיל בין שתי כתובות:
לכלל הרשימה, localhost:3000, ולהוספת פריט לרשימה, localhost:3000/add-item.בשביל הניתוב אנחנו צריכים בגוף הפונקציה הנ"ל לבדוק מה הנתיב עימו הגיעה הבקשה.
איפה נוכל לדעת את זה?עבור כך, וסתם ככה כפרקטיקה ספציפית לנוד שזו פלטפורמה עניה בתיעוד, נשתמש בכלי החזק שעומד לרשותנו: מצב הדיבאג של תוכנת Visual Studio Code (כמה ארוך! להלן VSCODE, אוקי?).
נקודות עצירה ומצב DEBUG בVSCODE
בא נחזור לקוד שלנו, ונשים נקודת עצירה בשורה 4, זו:
res.write('Hello World');
איך שמים נקודת עצירה? לוחצים בשורה הרצויה על השולים שלה שלשמאל מספר השורה. זה יצור שמה עיגול אדום יפה.
מאי משמע נקודת עצירה? זה כלי רב עוצמה בעורכי קוד של שפות תוכנה שמאפשרות מצב של "דיבאג" בה מריצים את התוכנה ואפשר לעצור אותה בשורה מסויימת שסומנה מראש לשם כך, ולצפות בערכי המשתנים המקומיים ולהבין מזה הרבה דברים.אחרי ששמנו נקודת עצירה נריץ את האפליקציה ע"י הקשה על F5, וניכנס לקישור הזה: http://localhost:3000/add-item. נחזור מייד לVSCODE, שם נמצא אותו עם שורה מודגשת, הלא היא שורה 4.
המצב כעת נקרא מצב DEBUG (שזה "פתרון בעיות קוד" בשפת מתכנתים - הפירוש המילולי הוא משהו כמו נטרול ג'וקים...).
יש שפע מידע שימושי מאוד במצב זה, ואני ממליץ בחום להכיר אותו בהמשך הרבה.
כעת נרחף עם העכבר על הפרמטר req בפונקציה, כדי לצפות בערכו האקטואלי נכון לרגע העצירה.
אני מצרף צילום מסך של החלון הצף שקופץ בעת ריחוף על המילה req:
חלון צף זה מראה לנו בעצם את ערכו של req... כפי שאתם רואים לא מדובר בערך יבש כמו טקסט או מספר, אלא באובייקט בעל המון מאפיינים שהVSCODE מראה בעץ מרשים... בעת שהעכבר על החלון הצף תוכלו לגלול כלפי מטה ולמצוא בתחתית הרשימה מאפיין צנוע בשם url שמכיל את הערך "/add-item". יש! אנחנו יכולים לעשות כעת ניתוב בסיסי לאפליקציה "רשימה" שהזמינו אצלנו.
רשות - פרקטיקות בסיסיות במצב הדיבאג
זה לא תמיד כ"כ נוח לחפש מאפיינים בעומק החלון הצף. יש דרכים ממוסדות יותר. לבדיקה של ערך באופן חד פעמי נוכל למטה בשורה שתחת החלונית debug console למצוא מקום בו ניתן להקליד כל ביטוי שנרצה וללחוץ על אנטר ולקבל את הערך שלו בהתאם לנקודת הזמן שלנו. למשל במקרה שלנו אפשר לכתוב שמה req.url וללחוץ אנטר.
.
אם נרצה לעקוב אחרי ערך שוב ושוב נוסיף אותו לחלונית watch שנמצאת בפאנל השמאלי. בלחיצה על סמל הפלוס שבכותרת החלון או בקליק ימני > add expression נוכל להוסיף ביטוי כמו req.url ותמיד לצפות בערך בכל עצירה שתהיה.בהודעה הבאה נכניס מין if בקוד של הפונקציה, לטיפול שונה במקרה שהreq.url שווה ל"/add-item".
-
המלצה / בקשה על מהות הפורום תכנות@מעלה-ומוריד אמר בהמלצה / בקשה על מהות הפורום תכנות:
השאלה שלו היתה מה המודל העסקי שלך... אתה משלם על זה... וזה לא:
האחזקה של השרת (לא רציני) והטרחה של תחזוקת האתר (רציני יותר), הם שוליים לדעתי בייחס לעזרה שאנשים (כולל אני, אבל כולל למשל את @Y-Excel-Access ואותך) מגישים פה.
לי יש שכר בדמות טובת הנאה של ניהול, זה מעמד יכולת וסיפוק. -
תחושת "עיניים ננעצות"תודה לכל המשתתפים בדיון,
אני מזכיר שהפורום מתאים רק לדיונים פרקטיים.
השאלה הפותחת אפשר להסתכל עליה כפרקטית, אם מפרשים אותה שהיא מבקשת מקורות ומראי מקומות, וככה נהגתי.
אבל הדיון בהמשך הוא לא מעשי, הוא מחשבתי, וזה סוג דיונים שהם טובים אבל לא מתאימים לפורום ולכלליו (דיונים כאלו צריכים מחשבה מיוחדת איך לנהלם ואיך להשגיח על איכותם שלא יהיו עקרים מתועלת או פוגעניים או מערערים וכדומה.). -
איך להמלט מאיכון משטרתי@nigun תודה, אתה לגמרי צודק ואני אכן ינעל.
אבל בקשת הסגירה שלך וגם הפניה ל@avr416 היא חד צדדית...
אתה מכיר מישהו שרבו נותן לגיטימציה לחוסר זהירות בעניין?
וכפי ש@avr416 אמר, עולה שאלה למה לא תכתוב את אותה הודעה גם בניסיון לעקוף חסימת אינטרנט?
העמדה של הפורום היא נורא פשוטה ותמימה, הלגיטימציה נקבעת לפי מה שהרבנים מורים לעשות. לפי מה שיודע לי, אם לא פספסתי משהו כל הרבנים מורים להיזהר מאוד בנושא הזה. -
שלום לכולם- חדשה פה@חינמי אתה מעלה בדעתך שהכסף הוא לצרכי פרנסה. ואז אתה משכנע אותי שחינם מביא יותר כסף.
אני רוצה איכות, יש לך דוגמה בה חינם הביאה איכות? לא. חינם הוא לא גורם לאיכות, במקרה הכי טוב הוא לא מפריע.בלי קשר לתוכניות של הפורום לגבי תשלום,
אני מציע בחום למי שמזדהה עם המחשבה שפרוג טועים,
לחפש בית מתאים כי פה זה לא מכמה סיבות. -
שלום לכולם- חדשה פהאני חושב שפרוג עשו דבר מאוד חכם שהם גובים כסף ממשתמשים כבדים (יותר מחמש הודעות ביום)
אנחנו לא נמצאים בכזה מקום (יש לנו אולי 3 אחוז מהתעבורה של פרוג ואולי פחות),
אבל בהחלט הייתי שוקל כזה דבר בנסיבות שהיה להם, ואולי גם הרבה קודם ובנסיבות הרבה פחות רציניות.
פורום בסגנו שלנון, וגם פרוג בימים הטובים שלו לפחות, זה כלי עבודה לכל דבר, ועל כלים משלמים (אצלנו, בינתיים, עוד לא).בקשר לחסרונות אחרים של אתרים אחרים, זה לא ראוי לכתוב פה. לא הייתי רוצה שיכתבו על הפורום הזה שום דבר רע בשום מקום.
-
למה אין עדיין פורום מחשבים חרדי מקצועי??אתייחס לזהות של הפורום, כי את השאלה הראשונה לא הבנתי.
הפורום הזה הוקם יחד עם גולן (שהוא חבר טוב שלי, מי שכעת בעלים של מקצועות.com) והוא בא לחבר בין האינטרסים שלי ושלו.
האינטרס שלי היה פלטפורמה מזמינה ומודרנית לפורום תכנות שכבר היה לי (code.613m.org, השרת היה שייך ל@magicode וגם שם המתחם), והאינטרס של גולן היה לפתוח פורום לתחומי האמנות בעיקר אבל על הדרך בכל הנושאים כדי שלא יצטרכו לנדוד על כל נושא.
בנינו יחד את הפורום הזה, ובאיזה שלב נפרדנו והוא הקים פורום נפרד.
מבחינתי כל הפורום הוא טפל לפורום תכנות (האקסקלוסיבי), הוא היה מטרת ההקמה והוא גם מקור ההכנסה והמוטיבציה להחזיק את הפורום כולו.האם פורום התכנות מוצלח? זה יחסי. כמובן שביחס לציפיות שיש לי, בכלל לא.
אבל ביחס לפורומים ישראלים קיימים, וביחס לסוג החומר של הגולשים בו (יהודים+ישראלים+חרדים) הוא לדעתי הצלחה יפה מאוד. -
sql - תכנון יצירת טבלאותגם השאלה וגם התשובות לא מספיק הבחינו בין מקרים.
אתה דיברת בשאלה ובהבהרות ההמשך שלה על כמה מקרים:- שדות כפולים לחיסכון JOIN, כלומר האם לגיטימי לשמור עותק של נתון בטבלה א' כדי להימנע מJOIN על כל צעד ושעל לטבלה ב'.
- שדות רבים של אותה ישות (קשר יחיד ליחיד) שתמיד בשימוש, ומתעורר צורך בפיצול רק בגלל גודלה של הטבלה, או בגלל הבדל מהותי במהות הפרטים הללו.
- כנ"ל, אבל שלא קיימים עבור כל ישות. למשל פרטי חשבון בנק, שלכל המשלמים באשראי יש בכלל פרטי אשראי. אז ישנם פרטי בנק ואשראי בקשר יחיד ליחיד לטבלת האנשים (יש מצב נדיר שיש שני ח-ן לאדם ולהיפך, אבל אני מתעלם מכך כעת).
- שדות דינמיים, כלומר שגם אחרי שהמוצר יהיה מושלם, יהיה צורך בשינויים (עריכה/הוספה/מחיקה של שדות) כשגרת השימוש במערכת.
1. מידע כפול לחיסכון בJOIN
לא לגיטימי כלל במסד נתונים רלציוני, ובשביל ביצועים יש לשנות מהלגיטימציה רק במקרי קיצון.
2. פיצול טבלה מרובת שדות לשני טבלאות עם קשר יחיד ליחיד
יש לעיתים הגיון בפיצול טבלה לשניים למרות שהשדות תמיד בשימוש ותמיד קשר של יחיד ליחיד. למשל אם אתה נוהג להשתמש ב* בחלק מהשאילתות שלך, שדות רבים שלא בשימוש שגרתי הם מכבידים על תוצאות השאילתה. כמו כן זה מיקל קצת על הבנת השדות, כי אפשר לקרוא להם בשמות קצרים יותר ("סניף" בטבת חשבונות בנק, יותר קל מאשר "סניף חשבון" וכדומה בטבלת האנשים).
עצם העובדה שיש כבר 150 שדות בטבלה זה לא עילה לדעתי לפצל טבלה.3. פיצול קבוצות של מידע אופציונלי מהטבלה
בעצם זה אותו מקרה של 2, רק שיש פה שני ייתרונות נוספים אפשריים
- מקום. שדות רבים ריקים תיאורטית לוקחים מקום, ומעשית יש להם עלות ביצועית למסד הנתונים. במקרה כזה הטבלה החדשה היא מה 0..1-1 כלומר לא לכל שורה יש שורה תאומה.
- מהות - נח בפיתוח ובתחזוקה להבין שקבוצת שדות מסויימת היא נושא מסויים.
- בדרך כלל זה בעצם ישויות נפרדות. למשל פרטי חשבון בנק זה לא תכונות של אדם אלא ישות שקוראים לה חשבון בנק. המציאות היא שישויות נפרדות יכולות בהמשך להפוך לרבים ליחיד או יחיד לרבים.
4. פיצול טבלה כדי להפריד שדות דינמיים משדות קבועים
אם התוכנה בנויה באופן שהיא עצמה יכולה להוסיף שדות/תכונות לישות, בהחלט מתבקש להפריד את זה מהטבלה שמחזיקה את נתוני הליבה. כמו"כ בגלל הרבה בעיות וקשיים בתחזוקת כזה דבר, וגם בגלל שעריכת מסד נתונים בזמן ייצור זה לא אמור להיות שגרה ברוכה, לכן מתבקש הפתרון של @clickone שזה EAV.