الدليل الشامل لترميز عناوين URL
تعرّف على كل ما يخص ترميز عناوين URL: ما هو، ولماذا يهم، وكيف يعمل الترميز بالنسبة المئوية (percent-encoding)، وأفضل الممارسات للتعامل مع الأحرف الخاصة في العناوين.
ما هو ترميز عناوين URL؟
ترميز عناوين URL، والمعروف أيضًا باسم الترميز بالنسبة المئوية (percent-encoding)، هو آلية لترميز المعلومات داخل مُعرّف الموارد الموحّد (URI) في ظروف معينة. ورغم أنه يُعرف بترميز عناوين URL، إلا أنه يُستخدم أيضًا بشكل أعم ضمن المجموعة الرئيسية لمُعرّف الموارد الموحّد (URI)، والتي تشمل كلًّا من محدد موقع الموارد الموحّد (URL) واسم الموارد الموحّد (URN).
يُعدّ هذا الترميز ضروريًا لأن عناوين URL لا يمكن إرسالها عبر الإنترنت إلا باستخدام مجموعة أحرف ASCII. وبما أن عناوين URL كثيرًا ما تحتوي على أحرف خارج مجموعة ASCII، فإنه يجب تحويل العنوان إلى صيغة ASCII صالحة. يستبدل ترميز عناوين URL أحرف ASCII غير الآمنة برمز % متبوعًا بخانتين ست عشريتين (hexadecimal).
كيف يعمل الترميز بالنسبة المئوية؟
تعمل آلية الترميز بالنسبة المئوية عن طريق تحويل كل حرف يحتاج إلى ترميز إلى بايت واحد أو أكثر. ثم يُمثَّل كل بايت برمز النسبة المئوية متبوعًا بخانتين ست عشريتين. وتمثّل الخانتان الست عشريتان قيمة البايت الخاصة بالحرف في الترميز المحدد (وعادةً ما يكون UTF-8).
على سبيل المثال، يتحول حرف المسافة (قيمته في ASCII هي 32، والقيمة الست عشرية 20) إلى %20. أما علامة العطف & (قيمتها في ASCII هي 38، والقيمة الست عشرية 26) فتتحول إلى %26. والأحرف غير التابعة لـ ASCII، مثل حرف e مع علامة النبرة الحادة، تُرمَّز أولًا إلى تسلسل البايتات الخاص بها بترميز UTF-8، ثم يُرمَّز كل بايت بالنسبة المئوية.
الأحرف المحجوزة مقابل غير المحجوزة
يُعرّف المعيار RFC 3986 فئتين من الأحرف لمُعرّفات URI: المحجوزة وغير المحجوزة. تشمل الأحرف غير المحجوزة الحروف الكبيرة والصغيرة (A-Z, a-z)، والأرقام (0-9)، والشرطات (-)، والنقاط (.)، والشرطات السفلية (_)، وعلامات التلدة (~). يمكن تضمين هذه الأحرف في مُعرّف URI دون ترميز.
أما الأحرف المحجوزة فلها معانٍ خاصة في بناء جملة عناوين URL، وتشمل: :، /، ?، #، [، ]، @، !، $، &، '، (، )، *، +، ,، ;، و=. وعندما تُستخدم هذه الأحرف داخل أحد مكونات URI خارج غرضها المحجوز، يجب ترميزها بالنسبة المئوية.
ترميز عناوين URL في اللغات المختلفة
JavaScript
توفّر لغة JavaScript زوجين من الدوال لترميز عناوين URL: encodeURI() / decodeURI() لترميز مُعرّفات URI الكاملة، وencodeURIComponent() / decodeURIComponent() لترميز مكونات URI الفردية. ويكمن الفرق الأساسي في أن encodeURI() تحافظ على الأحرف المحجوزة التي لها معنى خاص في مُعرّفات URI (مثل / و? و#)، بينما تقوم encodeURIComponent() بترميز جميع الأحرف غير الأبجدية الرقمية.
Python
توفّر وحدة urllib.parse في لغة Python الدالتين quote() وunquote() للترميز وفك الترميز الأساسيين، إضافةً إلى urlencode() لترميز القواميس (dictionaries) إلى سلاسل استعلام (query strings). وتقبل الدالة quote() معاملًا اختياريًا باسم safe لتحديد الأحرف التي ينبغي عدم ترميزها.
PHP
تقدّم لغة PHP الدالة urlencode() التي تُرمّز المسافات إلى + (وفقًا لصيغة application/x-www-form-urlencoded)، والدالة rawurlencode() التي تُرمّز المسافات إلى %20 (وفقًا للمعيار RFC 3986). ولفك الترميز، استخدم الدالتين urldecode() وrawurldecode() على التوالي.
أفضل الممارسات
- رمّز دائمًا مُدخلات المستخدم قبل تضمينها في عناوين URL
- استخدم
encodeURIComponent()لترميز قيم معاملات الاستعلام في JavaScript - استخدم
encodeURI()فقط عند ترميز مُعرّف URI كامل - التزم بنهج ترميز موحّد في جميع أنحاء تطبيقك
- افكك ترميز عناوين URL دائمًا على جانب الخادم قبل معالجتها
- اختبر ترميزك باستخدام أحرف خاصة، بما في ذلك أحرف Unicode
- لا تُرمّز عناوين URL ترميزًا مزدوجًا -- تحقّق دائمًا مما إذا كانت السلسلة مُرمّزة بالفعل