معالجة النماذج: GET مقابل POST
معالجة النماذج: GET مقابل POST
النماذج هي الطريقة الرئيسية التي يرسل بها المستخدمون البيانات إلى الخادم. سواء أكان صندوق تسجيل الدخول أم حقل البحث أم صفحة الدفع متعددة الخطوات، فإن كل نموذج HTML يوصل بياناته في النهاية على شكل طلب HTTP. يتناول هذا الدرس بالتفصيل كيفية عمل هذه الآلية، ولماذا يهم الاختيار بين GET وPOST، وكيف تقرأ خادمتك (servlet) قيم الحقول المُرسلة وتتحقق منها وتستخدمها بأمان.
كيف ترسل نماذج HTML البيانات
لكل نموذج HTML سمتان أساسيتان: method وaction. السمة action هي عنوان URL الذي يستقبل عملية الإرسال؛ أما method فتكون إما get أو post. عندما ينقر المستخدم على زر الإرسال، يحزّم المتصفح جميع حقول الإدخال المسمّاة في طلب HTTP ويرسله إلى ذلك العنوان.
يصبح كل <input name="..."> معاملًا في الطلب. سمة name هي المفتاح وقيمة الحقل هي القيمة. حقول الإدخال المتعددة التي تحمل الاسم ذاته تنتج قيمًا متعددة لذلك المفتاح — وهو ما تستخدمه خانات الاختيار (checkboxes) والقوائم متعددة التحديد تمامًا.
GET مقابل POST: الفرق الحقيقي
كلا الأسلوبين يوصلان المعاملات، لكنهما يختلفان في موضع البيانات وظهورها ودلالتهما.
- GET يُلحق المعاملات بعنوان URL كسلسلة استعلام:
/search?q=servlet&page=2. البيانات مرئية في شريط العنوان، ومحفوظة في سجل المتصفح، وقابلة للإشارة المرجعية (bookmark)، وقابلة للتخزين المؤقت. طلبات GET لا تغيّر الحالة — تكرارها لا يسبب أي تأثير جانبي. - POST يضع المعاملات في جسم طلب HTTP بعيدًا عن العنوان. لا إشارات مرجعية ولا تخزين مؤقت افتراضيًا. طلبات POST مخصصة لتغيير الحالة — إنشاء سجل، تقديم طلب، تسجيل الدخول.
doGet و doPost في خادمتك
يستدعي حاوي الخوادم (servlet container) التابعَ doGet لطلبات GET والتابعَ doPost لطلبات POST. تجاوز (override) أي من التابعين الذي يستخدمه نموذجك. خادمة تتعامل مع نموذج بحث (GET) ونموذج إرسال (POST) على عنوان URL ذاته تتجاوز كليهما:
قراءة معاملات الطلب
توفر واجهة HttpServletRequest عدة توابع للوصول إلى البيانات المُرسلة:
getParameter(name)— يُرجع القيمة الأولى (أو الوحيدة) لاسم الحقل كـString، أوnullإن لم يُرسَل المعامل أصلًا.getParameterValues(name)— يُرجعString[]بجميع القيم لذلك الاسم (خانات الاختيار والقوائم متعددة التحديد).getParameterMap()— يُرجعMap<String, String[]>غير قابل للتعديل يحتوي على كل معامل في الطلب، مفيد للتكرار والتسجيل.
getParameter() بالضبط ما أرسله العميل. تحقق دائمًا من الطول والصيغة والنطاق قبل استخدام أي قيمة. واهرب دائمًا من السلاسل التي يوفرها المستخدم بترميز HTML قبل كتابتها في الاستجابة — فعكس المدخلات غير المُهرَّبة مباشرةً يُعدّ ثغرة Cross-Site Scripting (XSS).
معالجة الحقول الرقمية والاختيارية
يصل كل معامل كـ String. التحويل مسؤوليتك، وقد يرمي استثناءات:
نمط Post-Redirect-Get (PRG)
بعد نجاح عملية POST، أعد التوجيه دائمًا — ولا تُوجّه (forward) إلى صفحة نجاح. إن وجّهت، يظل عنوان URL في المتصفح يشير إلى نقطة نهاية POST. وعندما يُحدّث المستخدم الصفحة، يُعيد المتصفح إرسال النموذج مما قد ينشئ سجلات مكررة أو يُكرر عملية دفع. إعادة التوجيه تغير عنوان URL في المتصفح إلى GET آمن، فتحديث الصفحة يُعيد تحميل صفحة النتيجة فحسب.
ترميز المحارف
إذا احتوى نموذجك على محارف غير ASCII (عربية أو صينية أو حروف لاتينية منقوطة) فيجب إخبار الحاوي بالترميز المستخدم في جسم الطلب قبل استدعاء getParameter للمرة الأولى:
في التطبيق الحقيقي، اضبط الترميز مرة واحدة في فلتر خادمة (servlet filter) بدلًا من تكراره في كل doPost. الحاويات الحديثة (Tomcat 10+ وJakarta EE 10) تستخدم UTF-8 افتراضيًا، لذا قد تكون هذه الخطوة مُعالَجة مسبقًا — لكن تحقق بدلًا من الافتراض.
الخلاصة
نماذج HTML ترسل البيانات كمعاملات HTTP. استخدم GET للعمليات الآمنة غير المغيِّرة للحالة، وPOST للعمليات التي تغيّر الحالة. تجاوز doGet وdoPost في خادمتك للتعامل مع كل أسلوب. اقرأ الحقول بـgetParameter وgetParameterValues؛ تحقق دائمًا من المدخلات وعقّمها قبل الاستخدام. أنهِ كل POST ناجح بإعادة توجيه (نمط PRG) لمنع الإرسال المزدوج. اضبط ترميز UTF-8 قبل قراءة المعاملات حين يقبل نموذجك مدخلات دولية.