ما الفرق بين encodeURI و encodeURIComponent؟
تقوم encodeURI بترميز عنوان URL كامل مع الحفاظ على الأحرف البنيوية مثل / و ? و #. أما encodeURIComponent فتقوم بترميز مكوّن واحد من الـ URI، فترمّز جميع الأحرف الخاصة بما في ذلك / و ? و &. استخدم encodeURIComponent لقيم معاملات الاستعلام و encodeURI لعناوين URL الكاملة.
ما هي encodeURI()؟
encodeURI() هي دالة مدمجة في جافاسكريبت مصمّمة لترميز معرّف موارد موحّد (URI) كامل. فهي تحوّل الأحرف غير الصالحة داخل الـ URI إلى ما يقابلها من percent-encoding، لكنها تحافظ عمداً على الأحرف ذات المعنى البنيوي داخل الـ URI.
وعلى وجه التحديد، فإن encodeURI() لا ترمّز الأحرف التالية: A-Z a-z 0-9 ; , / ? : @ & = + $ - _ . ! ~ * ' ( ) #. وهذا يعني أن البنية العامة لعنوان URL تبقى سليمة بعد الترميز.
// encodeURI() تحافظ على بنية عنوان URL
const url = 'https://example.com/my page?name=John Doe&city=New York';
console.log(encodeURI(url));
// "https://example.com/my%20page?name=John%20Doe&city=New%20York"
// لاحظ أن :, /, ?, &, و = لم تُرمَّز
هذا السلوك يجعل encodeURI() مثالية عندما يكون لديك عنوان URL كامل قد يحتوي على مسافات أو أحرف غير ASCII، لكن يجب أن تبقى أحرفه البنيوية (فاصل البروتوكول، ومحدّدات المسار، وعلامات سلسلة الاستعلام) كما هي.
ما هي encodeURIComponent()؟
encodeURIComponent() مصمّمة لترميز مكوّن واحد من الـ URI، مثل قيمة معامل استعلام أو جزء من المسار. وعلى خلاف encodeURI()، فهي ترمّز كل حرف خاص تقريباً، بما في ذلك الأحرف ذات المعنى البنيوي في عناوين URL.
الأحرف الوحيدة التي لا ترمّزها encodeURIComponent() هي: A-Z a-z 0-9 - _ . ! ~ * ' ( ). أما كل ما عداها، بما في ذلك / و ? و & و = و # و :، فيخضع لـ percent-encoding.
// encodeURIComponent() ترمّز كل شيء عدا الأحرف غير المحجوزة
const value = 'Tom & Jerry / Friends?';
console.log(encodeURIComponent(value));
// "Tom%20%26%20Jerry%20%2F%20Friends%3F"
// لاحظ أن &, /, و ? قد رُمِّزت
// بناء عنوان URL يحتوي على معامل استعلام
const url = 'https://example.com/search?q=' + encodeURIComponent(value);
// "https://example.com/search?q=Tom%20%26%20Jerry%20%2F%20Friends%3F"
ولأنها ترمّز الأحرف البنيوية، يجب ألّا تستخدم encodeURIComponent() أبداً على عنوان URL كامل. فالقيام بذلك سيرمّز ://، وجميع فواصل المسار /، ومحدّد الاستعلام ?، مما يجعل عنوان URL غير قابل للاستخدام.
أبرز الفروقات في لمحة سريعة
| الميزة | encodeURI() | encodeURIComponent() |
|---|---|---|
| الغرض | ترميز URI كامل | ترميز مكوّن من الـ URI |
ترميز / |
لا | نعم (%2F) |
ترميز ? |
لا | نعم (%3F) |
ترميز & |
لا | نعم (%26) |
ترميز = |
لا | نعم (%3D) |
ترميز # |
لا | نعم (%23) |
ترميز : |
لا | نعم (%3A) |
| ترميز المسافات | نعم (%20) |
نعم (%20) |
| ترميز Unicode | نعم | نعم |
متى تستخدم كل دالة
القاعدة بسيطة: استخدم encodeURI() عندما تريد ترميز عنوان URL كامل مع إبقاء بنيته صالحة. واستخدم encodeURIComponent() عندما تريد ترميز قيمة واحدة سيتم إدراجها داخل عنوان URL.
// السيناريو 1: ترميز عنوان URL كامل يحتوي على مسافات
const fullUrl = 'https://example.com/my documents/file name.pdf';
const encoded = encodeURI(fullUrl);
// "https://example.com/my%20documents/file%20name.pdf"
// السيناريو 2: بناء عنوان URL من أجزاء
const baseUrl = 'https://api.example.com/search';
const query = 'price >= 100 & category = books';
const finalUrl = baseUrl + '?q=' + encodeURIComponent(query);
// "https://api.example.com/search?q=price%20%3E%3D%20100%20%26%20category%20%3D%20books"
// السيناريو 3: ترميز عنوان URL لإعادة التوجيه كمعامل
const redirectUrl = 'https://example.com/callback?token=abc';
const loginUrl = 'https://auth.example.com/login?redirect=' +
encodeURIComponent(redirectUrl);
// يُرمَّز عنوان إعادة التوجيه بأكمله كقيمة معامل واحدة
الأخطاء الشائعة وكيفية تجنّبها
الخطأ 1: استخدام encodeURI() لقيم معاملات الاستعلام. لأن encodeURI() لا ترمّز & أو =، فإن استخدامها على قيمة معامل تحتوي على هذين الحرفين سيفسد بنية سلسلة الاستعلام.
// خطأ
const bad = 'https://example.com/search?q=' + encodeURI('salt & pepper');
// "https://example.com/search?q=salt%20&%20pepper"
// يرى الخادم q="salt " ومعاملاً إضافياً " pepper"
// صحيح
const good = 'https://example.com/search?q=' + encodeURIComponent('salt & pepper');
// "https://example.com/search?q=salt%20%26%20pepper"
الخطأ 2: استخدام encodeURIComponent() على عنوان URL كامل. هذا يدمّر بنية عنوان URL عبر ترميز جميع الشرطات المائلة والنقطتين وعلامات الاستفهام.
// خطأ
console.log(encodeURIComponent('https://example.com/path?key=value'));
// "https%3A%2F%2Fexample.com%2Fpath%3Fkey%3Dvalue"
// هذا لم يعد عنوان URL صالحاً!
// صحيح
console.log(encodeURI('https://example.com/path?key=value'));
// "https://example.com/path?key=value" (صالح أصلاً، لا شيء لترميزه)
الخطأ 3: الترميز المزدوج. إذا كانت السلسلة مرمّزة بالفعل بـ percent-encoding، فإن ترميزها مرة أخرى سيرمّز علامات %، فيحوّل %20 إلى %2520. تحقّق دائماً مما إذا كانت القيمة قد رُمِّزت بالفعل قبل تطبيق دوال الترميز.
وهناك بديل حديث أكثر أماناً وهو واجهتا URL و URLSearchParams، اللتان تتوليان الترميز تلقائياً وتساعدانك على تجنّب هذه المزالق تماماً.