العربية

أدوات المطور · URL التشفير وفك التشفير

لماذا + تصبح مسافة عندما تقوم بفك تشفير سلسلة استعلام، وعندما لا يحدث ذلك

· كيف يعمل

ترميز URL جافا سكريبت سير عمل المطور

تظل علامة الزائد وشكلها المشفر بنسبة مئوية متميزين من خلال أجهزة فك التشفير المختلفة
الرسم التوضيحي المتجه الأصلي ToolAcre

يعتمد ما إذا كانت + تعني المساحة على وحدة فك التشفير التي تتصل بها. يشرح هذا المنشور كيف يتعامل كل من decodeURIComponent وURLSearchParams وأطر عمل الخادم مع +، وكيفية تجنب تحويل علامة الجمع الحقيقية إلى مسافة.

لماذا + تصبح مسافة عندما تقوم بفك تشفير سلسلة استعلام، وعندما لا يحدث ذلك

تستخدم عمليات إرسال النماذج HTML تنسيق التطبيق /x-www-form-urlencoded، حيث تصبح المسافة زائد. يقوم الخادم الذي يتلقى الاسم=Alice+Smith باستبدال كل علامة زائد بمسافة قبل استخراج القيمة. عندما تنتمي علامة الجمع الحقيقية إلى البيانات، كما هو الحال في الحساب 5+3، فإنها تصل إلى الخادم كـ 5 3 بعد خطوة فك تشفير النموذج. هذا التحويل غير المرئي هو أصل الارتباك.

يؤدي فك التشفير JavaScript إلى نتائج مختلفة اعتمادًا على الوظيفة التي تستخدمها. يعامل URLSearchParams علامة الزائد كمساحة، مما يتوافق مع سلوك الخادم. لكن decodeURIComponent يترك الزائد دون تغيير، ويعامله حرفيًا. هذا عدم التناسق بين الوظائف هو سبب فك تشفير المدخلات نفسها بشكل مختلف. يكتشف المطور الذي يتوقع أن ينتج كلا جهازي فك التشفير نفس النتيجة أنهما لا يفعلان ذلك.

ترميزان متشابهان — RFC 3986 ترميز النسبة المئوية مقابل ترميز التطبيق/x-www-form-urlencoded

هناك معياران للتشفير يبدوان متشابهين ولكنهما يعملان بشكل مختلف. RFC 3986 يحدد الترميز المئوي: أي حرف يصبح %HH. تصبح المساحة %20. يضيف معيار application/x-www-form-urlencoded اختصارًا: يمكن أن تكون المساحة زائدًا. يعمل أي منهما في سياق النموذج، ولكن علامة plus اختيارية ومحددة لهذا المعيار. وهي مجالات مختلفة ذات مظهر مماثل.

ينطبق استدعاء decodeURIComponent على فك التشفير RFC 3986 فقط. يُقرأ %20 كمسافة وعلامة الجمع كعلامة زائد حرفية. يطبق URLSearchParams قواعد فك ترميز النموذج: تصبح نسبة الهروب المئوية أحرفها، وتصبح علامة الزائد مسافة. الوظيفتان تحلان نفس المشكلة في مجالات مختلفة. يؤدي مزجها إلى اختفاء علامة الجمع الحقيقية، أو أن تصبح المساحة علامة زائد وتفشل في التحويل.

decodeURIComponent يترك + وحده؛ يقوم URLSearchParams بتحويله إلى مسافة - مقارنة السلوكين JavaScript

يختلف سلوك الخادم، مما يؤدي إلى تفاقم المشكلة. يطبق Rails أو Django تلقائيًا قاعدة النموذج: تصبح علامة الزائد مسافة. لكن استخراج سلسلة الاستعلام الأولية وفك تشفيرها يدويًا باستخدام وحدة فك الترميز URL يترك الأمر سليمًا. نفس القيمة التي تتم معالجتها بواسطة أطر عمل مختلفة تنتج نتائج مختلفة. غالبًا ما يتعامل رمز الخادم مع هذا ضمنيًا، ويخفي المشكلة حتى تكتب وحدة فك ترميز مخصصة.

مثال: يقوم حقل رقم الهاتف بتخزين +1-555-0100 مع علامة الجمع كرمز البلد. يقوم النموذج HTML بترميزه كـ %2B1-555-0100 لأن JavaScript تم ترميزه بعلامة الجمع كـ %2B. يتلقى الخادم هذا. إذا تم تطبيق فك تشفير النموذج، يصبح %2B علامة زائد وتكون القيمة صحيحة. إذا قام الوكيل بإزالة التشفير، فإن استدعاء decodeURIComponent على النتيجة ينتج +1-555-0100. يتم فك تشفير كل طبقة مرة واحدة.

ما تفعله الخوادم - سلوك إطار العمل الشائع في سلسلة الاستعلام ونص الطلب، الموضح بعبارات عامة

يمكن لـ JavaScript تشفير القيم باستخدام encodeURIComponent. بالنظر إلى a+b، فإنه ينتج %2Bb. عندما تصل هذه السلسلة المشفرة إلى خادم أو وحدة فك ترميز مدركة للنموذج، يتم فك ترميز %2B كعلامة زائد وتكون النتيجة صحيحة. إذا قمت بالتشفير باستخدام قاعدة النموذج بدلاً من ذلك، تصبح المسافة علامة زائد وتصبح علامة الجمع الحقيقية %2B. وفي كلتا الحالتين، ينتج عن التشفير %2Bb. يعتمد التفسير على قاعدة فك التشفير التي تنطبق.

اختبار الرحلة ذهابًا وإيابًا: ابدأ بـ a+b. قم بالتشفير باستخدام encodeURIComponent للحصول على %2Bb. قم بفك تشفير %2Bb باستخدام decodeURIComponent واسترداد a+b. قم بتمرير a+b إلى URLSearchParams: فهو يعامل علامة الزائد كمسافة، وينتج a b. قم بتمرير a%2Bb إلى URLSearchParams للحصول على a+b مرة أخرى. نفس المدخلات التي تم فك تشفيرها بطريقتين تنتج مخرجات مختلفة اعتمادًا على وحدة فك التشفير التي تستخدمها.

مثال عملي: 'a+b' و'a%2Bb' من خلال كلا جهازي فك التشفير — أربع نتائج في جدول

الأخطاء الشائعة تتبع مباشرة. يقوم أحد المطورين بفك التشفير باستخدام decodeURIComponent ويتساءل عن سبب وجود فواصل حقيقية لبيانات النموذج الواردة. كان ينبغي عليهم استخدام URLSearchParams. على العكس من ذلك، يستخدم شخص ما URLSearchParams عندما يجب عليه استخدام decodeURIComponent، وتختفي كل علامة زائد حرفية. ينتج عن التشفير مرتين %252B، مما يتطلب أزواجًا متطابقة من التشفير وفك التشفير لفك التشفير بشكل صحيح.

خطأ آخر هو إنشاء سلسلة استعلام يدويًا كـ ?q=value بدون تشفير. يقوم أي علامة عطف أو يساوي في القيمة بإنشاء معلمة جديدة بدون مطالبة. لا يشكك المتصفح في التسلسل؛ فهو يتعامل مع النتيجة كما تم تشكيلها بشكل صحيح. فقط الترميز المتعمد باستخدام encodeURIComponent يمنع ذلك. يعرض برنامج التشفير ووحدة فك التشفير URL الوظائف الثلاث، ويكشف عن ما ينتجه كل منها.

الأخطاء الشائعة - فك التشفير مرتين، أو تشفير المسافة كـ + في مقطع المسار

تسمى قاعدة ترميز النموذج application/x-www-form-urlencoded لأنها تصف رأس نوع محتوى نص الطلب HTTP. نماذج HTML التي لا تحتوي على تحميلات للملفات ترسل النص الأساسي بهذا التنسيق. تستخدم سلاسل الاستعلام في عناوين URL هذه الاتفاقية أيضًا، على الرغم من عدم وجود معيار تشفير رسمي لها من الناحية الفنية. تتعامل مواصفات URL مع الاستعلام على أنه غير شفاف؛ زائد المعنى غير مكلف. ولكن في تطبيقات الويب، عادةً ما تعني علامة الزائد المساحة.

لضمان السلوك الصحيح، قم بالتشفير عمدًا وفك التشفير باستخدام وظيفة المطابقة. إذا قمت بالتشفير باستخدام encodeURIComponent، فقم بفك التشفير باستخدام decodeURIComponent. إذا كنت تقرأ بيانات النموذج HTML أو تطلب نصوصًا بتنسيق النموذج، فاستخدم URLSearchParams. لا تخمن أبدًا بناءً على المظهر. سلسلة مثل a+b غامضة. أجهزة فك التشفير غير قابلة للتبديل.

ما لا يغطيه هذا — بيانات النماذج متعددة الأجزاء ونصوص الطلب JSON

تحتوي بيانات النموذج متعدد الأجزاء وهيئات الطلب JSON والمعايير الأخرى على قواعد ترميز منفصلة. JSON لا يستخدم علامة الجمع لتشفير المسافة أو النسبة المئوية؛ يستخدم هروب Unicode. يستخدم Multipart حدودًا مختلفة. تتناول هذه المقالة سلاسل الاستعلام والنصوص المشفرة بالنموذج فقط، لأن هذا هو المكان الذي يظهر فيه الغموض الزائد. تحقق دائمًا من رأس Content-Type وRFC الذي يحدده.

قم دائمًا بتشفير علامة الجمع الحرفية كـ %2B عندما تنتمي إلى قيمة استعلام. يعرض برنامج التشفير ووحدة فك التشفير URL كيفية حماية علامة الزائد كـ %2B في وضع المكون، بشكل منفصل عن المسافات التي تصبح %20. مرر a+b وa%2Bb خلال كل وضع، ثم افحص النتائج. توضح هذه المقارنة سبب فك تشفير نفس المدخلات بشكل مختلف. الفرق هو السلوك الصحيح لمعيارين مختلفين.

الوجبات الجاهزة: قم دائمًا بتشفير علامة الجمع الحرفية كـ %2B — كيف يُظهر برنامج التشفير ووحدة فك التشفير URL الشكل الذي تبدو عليه القيمة كقيمة استعلام مشفرة بنسبة مئوية

الخلاصة: علامة الزائد في سلسلة الاستعلام هي اختصار ترميز النموذج للمسافة، وليست علامة زائد حرفية، إلا إذا جاءت من التشفير الذي يحميها كـ %2B. وحدة فك التشفير الخاطئة تفقد تلك الحماية. URLSearchParams هو الأكثر أمانًا في JavaScript الحديث؛ فهو يتعامل مع ترميز النموذج ويمنح الوصول إلى المعلمات المسماة. بالنسبة للسلاسل الأولية، يحمي encodeURIComponent كل شيء؛ يفسر decodeURIComponent %20 والنسب المئوية ولكنه يتعامل مع علامة الزائد حرفيًا.

اختبر هذا: أنشئ ?x=a+b يدويًا والصقه في برنامج التشفير ووحدة فك التشفير URL. افحصها وشاهد URLSearchParams يقسمها إلى معلمة x ذات القيمة a b. الصق ?x=a%2Bb وشاهد القيمة a+b. استخدم encodeURIComponent لإنشاء URL والمقارنة. يوضح هذا التأكيد المرئي القاعدة: قواعد النموذج تستخدم علامة الجمع، ويستخدم ترميز النسبة المئوية %20، وخلطها هو سبب اختفاء علامة الجمع في الفضاء.