בריחת מחרוזות JSON
ברחו טקסט כך שיהיה תקין בתוך מחרוזת JSON, או פענחו טקסט בָּרוּח בחזרה למה שהוא אומר — עם מיקום שגיאה מדויק.
הפלט יופיע כאן
מה הכלי הזה עושה
מחרוזת JSON לא יכולה להכיל מרכאה כפולה גולמית, בקסלאש גולמי או מעבר שורה גולמי — הפורמט זקוק לתווים האלה כדי לסמן היכן מחרוזות מתחילות ונגמרות. לכן הם נכתבים כרצפי בריחה, והכלי הזה ממיר בין שתי הצורות. הדביקו טקסט רגיל וקבלו את הגרסה הבָּרוּחה, מוכנה להשתלה ב-JSON; החליפו כיוון וטקסט בָּרוּח הופך קריא שוב.
הכיוון השני הוא זה שבגללו אנשים בדרך כלל מגיעים: שורת לוג, הודעת שגיאה או תשובת curl שחזרה כקיר של בקסלאשים. הכול רץ בדפדפן, וזה משנה כשמה שאתם מנסים לקרוא הוא תשובה מפרודקשן.
רצפי הבריחה
ל-JSON יש רשימה קצרה של רצפי בריחה, והכלי משתמש בדיוק בה — לא במשהו אקזוטי יותר, כי כל דבר אחר אינו JSON תקין.
- \" — מרכאה כפולה, שאחרת הייתה מסיימת את המחרוזת.
- \\ — בקסלאש בודד. זו הסיבה שנתיבי Windows ותבניות regex מוכפלים.
- \n ו-\r — מעבר שורה וחזרת גררה.
- \t — טאב. קיימים גם \b ו-\f, ל-backspace ול-form feed.
- \/ — בריחה אופציונלית ללוכסן. תקינה, אף פעם לא נדרשת; הכלי מקבל אותה ולעולם לא מייצר אותה.
- \uXXXX — כל תו לפי הקוד ההקסדצימלי שלו, וכך אפשר לכתוב תווי בקרה וכל דבר מחוץ ל-ASCII.
לתווי בקרה — כל מה שמתחת לקוד 32 — אין בכלל צורה מילולית בתוך מחרוזת JSON, ולכן הם תמיד יוצאים כרצפי \uXXXX גם כשלא ביקשתם פלט ASCII.
למה הבקסלאשים מתרבים
הסיבה הנפוצה ביותר להזדקק לכלי כזה היא טקסט שעבר בריחה יותר מפעם אחת. כל סבב קידוד בורח גם מהבקסלאשים שהסבב הקודם הכניס, וכך תו מרכאה בודד מגדל זנב ארוך והולך:
original He said "hi" escaped He said \"hi\" escaped x2 He said \\\"hi\\\"
זה קורה כשערך עובר סריאליזציה ל-JSON, ה-JSON הזה נשמר כמחרוזת בתוך מסמך JSON אחר, והתוצאה נכתבת ללוג. פענוח אחד מסיר שכבה אחת; הריצו שוב על התוצאה עד שהטקסט נקרא כרגיל. אם פענחתם ועדיין נשארו בקסלאשים, זו שכבה נוספת אמיתית ולא באג בהמרה.
מרכאות: ערך או מקטע
ערך מחרוזת JSON שלם כולל את המרכאות הכפולות העוטפות. אבל רוב הזמן אתם מדביקים לתוך מחרוזת שכבר קיימת בקוד או בקונפיג, ושם המרכאות האלה יהיו שגויות. לכן הבריחה מפיקה כברירת מחדל את התוכן הבָּרוּח בלבד, ואפשרות «כלול מרכאות עוטפות» מוסיפה אותן כשרוצים ערך שאפשר להדביק כמו שהוא.
הפענוח לא זקוק לבחירה כזאת — הוא מקבל את שתי הצורות. הדביקו מקטע או הדביקו ערך מצוטט שלם ישר מתוך מסמך JSON, והמרכאות העוטפות יזוהו ויוסרו.
יוניקוד, ומתי כן לברוח ממנו
JSON הוא פורמט יוניקוד. "שלום" ו-"😀" הן מחרוזות JSON תקינות לחלוטין בדיוק כפי שנכתבו, והשארתן קריאות היא ברירת המחדל כאן. אפשרות ה-\uXXXX קיימת עבור המערכות שלא התעדכנו: צינורות לוגים ישנים, טרמינלים ופרסרים שמניחים ASCII ומעוותים כל דבר אחר.
פרט אחד חשוב כשהאפשרות דלוקה. תווים מחוץ לטווח הבסיסי — רוב האמוג׳י — נשמרים פנימית כשתי יחידות שנקראות צמד surrogate, והפורמט דורש ששני החצאים ייכתבו כרצפים נפרדים. לכן אמוג׳י הופך לשני רצפי \u ולא לרצף אחד ארוך יותר. כלים שטועים בזה מייצרים רצפים ששום פרסר לא מקבל — וזה ההסבר הרגיל לאמוג׳י ששורד מערכת אחת ונשבר בבאה אחריה.
כשהפענוח נכשל
לא כל רצף בקסלאש הוא בריחה תקינה. \q לא אומר דבר ב-JSON, ו-\u12 הוא רצף \u שחסרות לו חצי מהספרות. במקום להעביר אותם כמות שהם ולהחזיר פלט שנראה תקין ואינו מה שהנתונים שלכם אמרו, הכלי נעצר ומדווח על השורה והעמודה המדויקות שבהן הרצף השבור מתחיל.
בפועל השגיאה הזאת אינפורמטיבית: \q תועה בדרך כלל אומר שהטקסט מעולם לא עבר בריחת JSON מלכתחילה, ו-\u קטוע בדרך כלל אומר שהקלט נחתך — שורת לוג שנקטמה במגבלת אורך, או העתקה שנעצרה באמצע רצף.
שאלות נפוצות
- למה יש בטקסט שלי \\" בכל מקום?
- הוא עבר בריחה יותר מפעם אחת. כל סבב בורח מהבקסלאשים של הסבב הקודם, כך שלמרכאה מקורית אחת יכולים להתלוות כמה. פענחו שוב ושוב — כל ריצה מסירה בדיוק שכבה אחת — עד שהטקסט נקרא כרגיל.
- האם להפעיל את המרכאות העוטפות?
- רק אם אתם רוצים ערך JSON שלם להדבקה כמות שהוא, למשל כצד ימין שלם של מפתח. אם אתם מדביקים לתוך מחרוזת שכבר קיימת בקוד — השאירו כבוי, אחרת תקבלו מרכאות בתוך מרכאות.
- האם עברית, ערבית, סינית או אמוג׳י צריכים בריחה?
- לא. מחרוזות JSON הן יוניקוד, ולכן התווים האלה תקינים כמות שהם ונשארים קריאים כברירת מחדל. הפעילו את אפשרות ה-\uXXXX רק כשמערכת בהמשך השרשרת מתעקשת על ASCII בלבד; אז אמוג׳י נכתב כשני רצפי ה-surrogate הנדרשים.
- מה המשמעות של «רצף בריחה לא חוקי»?
- הקלט מכיל בקסלאש ואחריו משהו ש-JSON לא מגדיר, כמו \q, או \u בלי ארבע ספרות הקסדצימליות אחריו. המיקום מדווח כדי שתוכלו להסתכל בדיוק שם: בדרך כלל הטקסט לא עבר בריחת JSON מלכתחילה, או שהוא נקטע באמצע.
- האם הטקסט שלי נשלח לאנשהו?
- לא. גם הבריחה וגם הפענוח רצים כולם בדפדפן שלכם, כך שטוקנים, payloads ושורות לוג לעולם לא עוזבים את המכשיר.