הפסיקו לפענח URLs עם טריקים של מחרוזות
לפני שה-API של URL היה קיים, אנשים חתכו כתובות עם split('?'), ביטויים רגולריים ותקווה. זה עבד ברוב המקרים, עד שערך הכיל &, =, רווח או תו שאינו ASCII, ואז זה הפסיק לעבוד. גם הדפדפן וגם Node מגיעים עם parser אמיתי. השתמשו בו.
קריאה אחת, וכל חלק של הכתובת כבר מפורק ומפוענח נכון. ה-constructor זורק TypeError על קלט לא תקין, ובדרך כלל זה מה שרוצים: כתובת זבל צריכה להיכשל ברעש, ולא לייצר בשקט זבל בהמשך הדרך.
קריאת פרמטרים של Query
לכל URL יש מאפיין .searchParams: אובייקט URLSearchParams שיודע לקרוא ולכתוב את ה-query string:
כמה דברים ששווה לשים לב אליהם:
- הערכים חוזרים כבר מפוענחים.
?name=Ada%20Lovelaceנותן לכם"Ada Lovelace". - הכול מחרוזת.
"2"הוא לא2. המירו עםNumber()אם אתם צריכים מספר. - מפתחות שחוזרים על עצמם הם חוקיים.
getמחזיר את ההתאמה הראשונה;getAllמחזיר את כל ההתאמות. - מפתחות חסרים מחזירים
null, לאundefined, ולכן?? "default"עובד איתם מצוין.
בניית Query String
אפשר לבנות query string מאפס עם URLSearchParams, בלי escape ידני ובלי חיבור עם &:
או ליצור אותו מאובייקט: כל iterable של זוגות [key, value] עובד, וגם אובייקט רגיל:
set מול append: set מחליף כל ערך קיים של אותו מפתח. append מוסיף עוד ערך. השתמשו ב-append כשמפתח יכול לחזור באופן לגיטימי (תגיות, מסננים); השתמשו ב-set לפרמטרים עם ערך יחיד.
שינוי URL
מכיוון ש-URL הוא אובייקט חי, שינוי של searchParams מעדכן אוטומטית את .search ואת .href:
זו הדרך המקובלת להוסיף פרמטר query לכתובת קיימת. בלי בדיקה של "האם כבר יש בכתובת ?", בלי לדאוג אם להוסיף לפני כן & או ?.
אפשר לשנות חלקים אחרים של הכתובת באותה דרך:
מעבר על הפרמטרים
URLSearchParams הוא iterable. for...of נותן לכם זוגות [key, value], ויש גם את העוזרים הרגילים keys(), values() ו-entries():
שימו לב שמפתחות שחוזרים מופיעים כמה פעמים: תראו tag = web ואחריו tag = beginner כרשומות נפרדות. זה נאמן ל-query string האמיתי.
אם אתם רוצים אובייקט רגיל להדפסת דיבוג מהירה, Object.fromEntries עובד, אבל הוא מאחד מפתחות חוזרים ושומר רק את הערך האחרון:
בסדר לדיבוג. שגוי אם מפתח כלשהו יכול לחזור.
כתובות יחסיות צריכות בסיס
new URL("/search?q=js") לבדו זורק שגיאה: נתיב יחסי הוא לא URL תקין בפני עצמו. העבירו בסיס כארגומנט השני:
חוקי הפתרון זהים לאלה שדפדפנים משתמשים בהם עבור <a href>: / בהתחלה הוא נתיב מוחלט מה-host, בלי לוכסן זה יחסי לנתיב הנוכחי, ו-.. עולה רמה. שימושי מאוד כשמרכיבים כתובות API מבסיס מוגדר.
בדפדפן, window.location.href הוא בסיס מוכן לפענוח הכתובת של העמוד הנוכחי:
const u = new URL(window.location.href);
const page = u.searchParams.get("page") ?? "1";
טיפול בכתובות לא תקינות
ה-constructor של URL זורק שגיאה על קלט פגום. זה שימושי, אבל זה אומר שצריך try/catch כשמפענחים כל דבר שהמשתמש הקליד או שמערכת חיצונית שלחה:
סביבות מודרניות חושפות גם את URL.canParse(input): בדיקה בוליאנית שחוסכת את ריקוד ה-try/catch כשרק רוצים לאמת:
דוגמה קטנה שעובדת
מחברים הכול יחד: קוראים את המסננים הנוכחיים מכתובת, משנים אותם ומפיקים כתובת חדשה לניווט:
העברת null מוחקת את הפרמטר. כל ערך אחר מגדיר אותו או דורס אותו. זה דפוס שתכתבו בצורה כזו או אחרת בכל פעם שתבנו ממשקי סינון, עימוד או deep links.
מה לקחת מכאן
new URL(string)מפענח כתובת לחלקים עם שמות. הוא זורק שגיאה על זבל.url.searchParamsהואURLSearchParams: השתמשו ב-get,getAll,set,append,delete,has.- הקידוד קורה בשבילכם. אל תשתמשו ב-
encodeURIComponentאלא אם אתם בונים מחרוזות ביד. - העבירו כתובת בסיס כארגומנט השני כדי לפתור נתיבים יחסיים.
URL.canParse(אוtry/catch) הוא כלי האימות שלכם לקלט לא מהימן.
בכל פעם שאתם מתפתים לפצל כתובת עם .split('?') או לשלוף פרמטר query עם regex, השתמשו ב-APIs האלה במקום. הם קצרים יותר, נכונים, וכבר נמצאים בסביבת הריצה.
שאלות נפוצות
איך מפענחים URL ב-JavaScript?
העבירו את המחרוזת ל-constructor של URL: const u = new URL('https://example.com/path?x=1'). האובייקט שמתקבל חושף את protocol, host, pathname, search, hash ועוזר בשם searchParams. הוא זורק שגיאה על כתובות לא תקינות, אז עטפו אותו ב-try/catch כשמפענחים קלט לא מהימן.
איך מקבלים פרמטר של query string ב-JavaScript?
השתמשו ב-url.searchParams.get('name'). הוא מחזיר את הערך אחרי פענוח, או null אם הפרמטר לא קיים. עבור פרמטרים שיכולים לחזור על עצמם (?tag=a&tag=b), השתמשו ב-searchParams.getAll('tag') כדי לקבל את כל הערכים כמערך.
מה ההבדל בין URL ל-URLSearchParams?
URL מפענח ומייצג כתובת שלמה: פרוטוקול, host, נתיב, query ו-hash. URLSearchParams הוא רק החלק של ה-query string, ואפשר להשתמש בו לבד כדי לבנות או לפענח מחרוזות כמו a=1&b=2. לכל מופע של URL יש מאפיין .searchParams, שהוא URLSearchParams שקשור לאותה כתובת.
האם צריך לקודד פרמטרים של query ידנית?
לא. URLSearchParams מקודד מפתחות וערכים אוטומטית כשקוראים ל-set או ל-append, או כשקוראים בחזרה את המחרוזת. הוא מטפל נכון ברווחים, ב-&, ב-= וב-Unicode. השתמשו ב-encodeURIComponent רק כשאתם בונים מחרוזת ביד, ובדרך כלל לא כדאי לעשות זאת.