שינוי קל של כתובות אתרים באמצעות URLSearchParams

ה-API של URLSearchParams מספק ממשק עקבי לחלקים השונים של כתובת ה-URL ומאפשר לבצע מניפולציות פשוטות במחרוזת השאילתה (החלק שמופיע אחרי ?).

באופן מסורתי, מפתחים משתמשים בביטויים רגולריים ובחלוקת מחרוזות כדי לחלץ את פרמטרים של שאילתות מכתובת ה-URL. אם נהיה כנים עם עצמנו, זה לא כיף. התהליך הזה יכול להיות מייגע ומועד לשגיאות. אחד מהסודות האפלים שלי הוא שהשתמשתי שוב ושוב באותן שיטות עזר של get|set|removeURLParameter בכמה אפליקציות גדולות של Google.com, כולל מעקב סנטה של Google ואתר Google I/O 2015.

הגיע הזמן לממשק API מתאים שיעשה את הדברים האלה בשבילנו!

URLSearchParams API

לניסיון הדגמה

ב-Chrome 49 מוטמע URLSearchParams ממפרט כתובות ה-URL, ממשק API שמאפשר לבצע שינויים בפרמטרים של שאילתות של כתובות URL. אני רואה ב-URLSearchParams יתרון נוח כמו כתובות URL, כמו ש-FormData היה יתרון נוח בטפסים.

אז מה אפשר לעשות איתו? אם נתונה מחרוזת של כתובת URL, אפשר לחלץ בקלות את ערכי הפרמטרים:

// Can also constructor from another URLSearchParams
const params = new URLSearchParams('q=search+string&version=1&person=Eric');

params.get('q') === "search string"
params.get('version') === "1"
Array.from(params).length === 3
for (let p of params) {
    console.log(p);
}

set ערך פרמטר:

params.set('version', 2);

להוסיף ערך נוסף לפרמטר קיים:

params.append('person', 'Tim');
params.getAll('person') === ['Eric', 'Tim']

מחיקת פרמטרים:

params.delete('person');

עבודה עם כתובות URL

ברוב המקרים, סביר להניח שתעבדו עם כתובות URL מלאות או שתשנו את כתובת ה-URL של האפליקציה. ה-constructor של URL יכול להיות שימושי במיוחד במקרים הבאים:

const url = new URL('https://example.com?foo=1&bar=2');
const params = new URLSearchParams(url.search);
params.set('baz', 3);

params.has('baz') === true
params.toString() === 'foo=1&bar=2&baz=3'

כדי לבצע שינויים בכתובת ה-URL בפועל, אפשר לשלוף פרמטרים, לעדכן את הערכים שלהם, ואז להשתמש ב-history.replaceState כדי לעדכן את כתובת ה-URL.

// URL: https://example.com?version=1.0
const params = new URLSearchParams(location.search);
params.set('version', 2.0);

window.history.replaceState({}, '', `${location.pathname}?${params}`);
// URL: https://example.com?version=2.0

כאן השתמשתי במחרוזות תבנית של ES6 כדי לשחזר כתובת URL מעודכנת מנתיב כתובת ה-URL הקיים של האפליקציה ומ-params ששונו.

שילוב עם כתובות URL של מקומות אחרים

כברירת מחדל, שליחת FormData בבקשת API מסוג fetch() יוצרת גוף מרובות חלקים. אם יש צורך, URLSearchParams מספק מנגנון חלופי לנתוני POST שמקודדים כ-URL במקום כ-MIME multipart.

const params = new URLSearchParams();
params.append('api_key', '1234567890');

fetch('https://example.com/api', {
    method: 'POST',
    body: params
}).then(...)

הוא עדיין לא מוטמע ב-Chrome, אבל URLSearchParams משתלב גם עם ה-constructor‏ URL והתגים a. שניהם תומכים בחבר החדש שלנו על ידי אספקת נכס לקריאה בלבד, .searchParams כדי לגשת לפרמטרים של שאילתות:

const url = new URL(location);
const foo = url.searchParams.get('foo') || 'somedefault';

קישורים מקבלים גם נכס .searchParams:

const a = document.createElement('a');
a.href = 'https://example.com?filter=api';

// a.searchParams.get('filter') === 'api';

זיהוי תכונות ותמיכה בדפדפנים

נכון לעכשיו, Chrome 49, Firefox 44 ו-Opera 36 תומכים בURLSearchParams.

if ('URLSearchParams' in window) {
    // Browser supports URLSearchParams
}

למילוי פוליגונים, מומלץ להשתמש בתבנית בכתובת github.com/WebReflection/url-search-params.

הדגמה (דמו)

כדאי לנסות את הדוגמה.

כדי לראות את URLSearchParams באפליקציה בעולם האמיתי, אפשר להיעזר ביוצר ערכות הסמלים של Polymer ל-Material Design. השתמשתי בו כדי להגדיר את המצב הראשוני של האפליקציה מקישורי עומק. שימושי מאוד :)