كانت مكالمة API الخاصة بك صحيحة. كانت النقطة النهائية مطابقة، وكانت الرؤوس صحيحة، وردت الإجابة بـ 400 Bad Request. بعد عشرين دقيقة من النظر إليها، تلاحظ المشكلة: عنوان بريد إلكتروني في سلسلة الاستعلام الذي يحتوي على + علامة — والتي تم تفسيرها من قبل الخادم كمسافة. هذا هو مثال على الترميز المئوي، ويؤدي إلى مشاكل صعبة التصحيح.
يغطي هذا الدليل ما يفعله الترميز المئوي حقًا، وما هي الأحرف التي يجب ترميزها في السياقات المختلفة، والمشكلة الشائعة في برمجة JavaScript، وكيفية استخدام أداة مثل مشفر/فك تشفير URL لتحقق من عملك.
ما يفعله الترميز المئوي حقًا
يمكن أن تحتوي الـ URL فقط على مجموعة محدودة من أحرف ASCII. كل شيء آخر — المسافات، الأحرف الدولية، الرموز التي لها معنى خاص في الـ URL — يجب أن يُحول إلى صيغة آمنة قبل الإرسال.
يقوم الترميز المئوي بذلك عن طريق استبدال كل حرف غير آمن بعلامة في المئة متبوعة بحدين عشريًا. تصبح المسافة %20، تصبح العلامة %23، تصبح علامة التصنيف %2F. جاء الاسم من هذه العلامة المبكرة.
يحدد المعيار (RFC 3986) "الأحرف المسموح بها" التي لا تحتاج إلى ترميز: الأحرف الأبجدية (A-Z، a-z)، الأرقام (0-9)، ورابع رموز: - _ . ~. كل شيء آخر إما حرف مُحتفظ به (يُستخدم لتحديد هيكل الـ URL) أو يجب ترميزه.
الأحرف التي تؤدي إلى تلف الأنظمة
إليك الأحرف التي تسبب أضرارًا كبيرة في الممارسة:
| حرف | ترميز | السياقات التي تتطلب الترميز | ملحوظات |
|---|---|---|---|
| فضاء | %20 | جميع السياقات | يُرمَّز أيضًا كـ + في بيانات النموذج — انظر أدناه |
| & | %26 | قيم سلسلة الاستعلام | تُستخدم لفصل معلمات الاستعلام؛ يجب ترميزها داخل القيمة |
| = | %3D | قيم سلسلة الاستعلام | تُستخدم لفصل المفتاح عن القيمة؛ يجب ترميزها داخل القيمة نفسها |
| + | %2B | قيم سلسلة الاستعلام | تُحلّل كمسافة في ترميز النموذج — استخدم %2B لأي مسافة حرفيّة |
| # | %23 | المسار، سلسلة الاستعلام | تُستخدم لتحديد الجزء المتبقي؛ لا يتم إرسال أي شيء بعد ذلك إلى الخادم |
| ? | %3F | أجزاء المسار، قيم سلسلة الاستعلام | تبدأ سلسلة الاستعلام؛ يجب ترميزها في المسار أو القيم |
| / | %2F | أجزاء المسار (عند القيمة الحرفيّة) | تُستخدم لفصل أجزاء المسار؛ يجب ترميزها داخل قيمة الجزء |
| @ | %40 | قيم سلسلة الاستعلام | يجب ترميز عنوان البريد الإلكتروني في معلمات الاستعلام |
ثلاثة سياقات، قواعد مختلفة
يختلف الجزء الذي تُرمّز فيه الـ URL ما يُحتاج إلى ترميزه.
الرابط الكامل — عندما يكون لديك رابط كامل لنقله، ترغب في الحفاظ على هيكله. تبقى علامات التصنيف، الأسئلة، وعلامات التصنيف كما هي. فقط الأحرف خارج المجموعة المسموح بها تُرمّز.
قيمة سلسلة الاستعلام — هذا هو المكان الذي يعيش فيه معظم أخطاء الـ API. يجب ترميز كل قيمة في سلسلة الاستعلام بحيث لا تظهر الرموز المستخدمة لبناء الاستعلام (&, =, #, +) حرفيًا داخل القيمة. إذا كان اسم المستخدم "جون & جين"، يجب أن تقرأ سلسلة الاستعلام كالتالي name=John%20%26%20Janeالقيم المنطقية تبقى كنصوص. name=John & Jane (التي تُحلّل من قبل الخادم كمعلمتين منفصلتين).
أجزاء المسار — أجزاء المسار هي الجزء بين علامات التصنيف. إذا تحتوي أجزاء المسار على علامة تنصيف (مثلاً اسم ملف يحتوي على علامة تنصيف)، يجب ترميزها كـ %2F. بعض الخوادم تُعتبر %2F في المسار كمشكلة أمنية؛ تعرف خلفية الخادم قبل استخدام هذا.
encodeURI مقابل encodeURIComponent — المعضلة في برمجة JavaScript
يقدم لك JavaScript دالة ترميز مدمجة، وغالبًا ما تكون الأخطاء الناتجة عن استخدام الدالة الخاطئة.
// encodeURI — encodes a full URL
// Preserves: : / ? # [ ] @ ! $ & ' ( ) * + , ; =
encodeURI("https://example.com/search?q=hello world&lang=en")
// → "https://example.com/search?q=hello%20world&lang=en"
// Note: & and = are NOT encoded — the query structure is preserved
// encodeURIComponent — encodes a single value
// Encodes everything except: A-Z a-z 0-9 - _ . ! ~ * ' ( )
encodeURIComponent("hello world&lang=en")
// → "hello%20world%26lang%3Den"
// Note: & and = ARE encoded — safe to use as a query value
// The bug: using encodeURI on a value
encodeURI("hello world&lang=en")
// → "hello%20world&lang=en" ← & survives! Server sees two parameters.
// The correct approach for building query strings
const name = "John & Jane"
const email = "john+jane@example.com"
const url = `https://api.example.com/users?name=${encodeURIComponent(name)}&email=${encodeURIComponent(email)}`
// → "https://api.example.com/users?name=John%20%26%20Jane&email=john%2Bjane%40example.com"
مبدأ عام: استخدم encodeURIComponent على القيم الفردية قبل وضعها في رابط. استخدم encodeURI فقط عندما يكون لديك رابط كامل وترغب في تنظيفه دون تدمير هيكله.
العلامة +: الترميز في ترميز النموذج مقابل الترميز المئوي
عندما يُقدّم نموذج HTML بـ method="GET"، تُرمّز البيانات باستخدام application/x-www-form-urlencoded. في هذا التنسيق، تصبح المسافات + بدلاً من %20. العديد من أنظمة الخوادم (مثل PHP، Django، Rails) تُحلّل + كمسافة في سلسلة الاستعلام.
يؤدي ذلك إلى مشكلة عندما تحتوي القيمة على علامة + حقيقية — مثل رقم هاتف +44 7700 900000. إذا قمت بتمريرها كـ +44...، فإن الخادم يُحلّل العلامة + كمسافة ويحصل على 44.... الحل هو ترميز العلامة + الحرفيّة كـ %2B، والتي تبقى محفوظة تمامًا في كلا النماذج.
للمهام الحديثة في الـ API، اعتمد على %20 لأي مسافة (ما يُنتجها encodeURIComponent ) بدلًا من الاعتماد على +.
الترميز المزدوج: عندما يُحدث الترميز خطأ
يحدث الترميز المزدوج عندما تُرمّز قيمة مُترمّزة بالفعل. تُرمّز علامة في المئة في %20 إلى %2520 — تُحلّل %25 إلى علامة في المئة حرفيًا، مما يعطيك النص %20 بدلًا من المسافة.
يظهر هذا عادةً في الحالات التالية:
- تُخزن رابط في قاعدة البيانات وتُرمّز مرة أخرى قبل استخدامه
- تُرمّز القيم التي قمت بترميزها يدويًا من قبل مكتبة أو إطار عمل
- أنت تُنشئ رابط يحتوي على رابط آخر كمعلمة
لتجنب ذلك: ترمّز مرة واحدة فقط، عند نقطة تكوين الرابط. إذا كنت غير متأكد من أن القيمة مُترمّزة بالفعل، فقم أولاً بتفكيكها (باستخدام decodeURIComponent)، ثم أعد ترميزها بشكل نظيف.
استكشاف الترميز المئوي في أدوات التحليل
عندما تُظهر طلب API سلوكًا غير متوقع، افتح أدوات التحليل (F12)، انتقل إلى علامة الشبكة، وانقر على الطلب المُتعطل. تحت الرؤوس، ابحث عن رابط الطلب — يُعرض في صيغته الخام بعد الترميز. تحت المحتوى، يمكنك رؤية المعلمات المُفككة مرة أخرى إلى قيمها الأصلية، مما يسهل رؤية ما إذا كانت علامة وصلت كمُفصّل أو تم تمريرها كقيمة حرفيّة.
للاختبار اليدوي، أداة ترميز وفك الترميز عبر الإنترنت تسمح لك بوضع نص ورؤية ما يظهره الترميز المُعدّل — مفيدة لفحص القيم قبل إدراجها في طلب. الأداة IO Tools مُرمّز/مُفكّك الرابط تُعالج الاتجاهين وتُظهر النتيجة فورًا.
تثبيت ملحقاتنا
أضف أدوات IO إلى متصفحك المفضل للوصول الفوري والبحث بشكل أسرع
恵 وصلت لوحة النتائج!
لوحة النتائج هي طريقة ممتعة لتتبع ألعابك، يتم تخزين جميع البيانات في متصفحك. المزيد من الميزات قريبا!
