نکات و ابهاماتی درمورد کاربرد متدهای GET و POST – متدهای Idempotent و غیر Idempotent

میدونید که پروتکل HTTP متدهای مختلفی داره که متداول ترین اونا که توسعه دهندگان وب باهاشون سروکار دارن، متدهای GET و POST هستن.
متد GET همون متدی هست که موقع فراخوانی مستقیم آدرسها اجرا میشه. مثلا موقعی که روی یک لینک کلیک میکنید. در این روش تمام متغییرها، درصورت وجود، در URL ارسال میشن.
متد POST متدی هست که برای ارسال فرمها استفاده میشه. در این روش تمام متغییرهای فرم در بدنهء درخواست HTTP ارسال میشن و در URL وجود ندارن و دیده نمیشن. البته URL ای که یک درخواست POST بهش ارسال میشه میتونه شامل پارامترهای URL هم باشه که به اینصورت میشه گفت اطلاعات دیگه ای رو هم (البته معمولا بصورت ثابت و hard-code شده) در URL مشخص و ارسال کردیم، اما متد استفاده شده بهرحال POST هست و نه GET، چون درخواست HTTP ما محتوی دیتای ارسالی توسط کاربر در بندهء خودش هست و متدی که توسط مرورگر در درخواست مشخص میشه از نوع POST خواهد بود.

تگ فرمی با متد GET به این شکل نوشته میشه:

<form ... method="get">

و تگ فرمی که اطلاعات رو با متد POST ارسال میکنه به این شکل:

<form ... method="post">

بر اساس پروتکل HTTP، متد GET نباید برای درخواست هایی که هربار اجرای اونها موجب تغییری در سرور میشه مورد استفاده قرار بگیره. اونطور که بنده فهمیدم، کاربرد اصلی متد GET برای دریافت اطلاعات هست، نه ارسال اطلاعاتی که بخصوص هر بار باعث ایجاد تغییراتی در سمت سرور میشن. شاید از اسم این متد هم بشه به هدف واقعی اون که گرفتن اطلاعات موجود بر روی سرور هست، و نه ذخیره کردن یا تغییر دادن چیزی، پی برد.

بطور مثال این لینک رو درنظر بگیرید:

http://yoursite.com/add_credit.php?to=3546&amount=500

همونطور که باید قابل حدس باشه، این لینک باعث میشه که مقدار 500 تا اعتبار به کاربری با آیدی 3546 اضافه بشه. مسلما اجرای این درخواست موجب تغییر وضعیتی در سمت سرور میشه. یعنی مقدار اعتبار کاربر در دیتابیس به ازای هربار فراخوانی این لینک اضافه میشه. ضمنا این فقط فراخوانی بار اول نیست که تغییر ایجاد میکنه، بلکه هربار فراخوانی وضعیت سمت سرور رو تغییر میده و اثر جدیدی میذاره. تغییری که بر اثر دو درخواست پشت سرهم ایجاد میشه برابر با اثر یک درخواست نیست.

گرچه چنین کاربردهایی که مثال زدیم خیلی متداول هستن، اما در اصل این کاربردها برخلاف استانداردهای ذکر شده در پروتکل HTTP هستن.
خب این طبیعی هست چون خیلی افراد از این قضیه اطلاع ندارن و البته شاید یکی از دلایل دیگر این نقض استاندارد هم این باشه که کار کردن با متد GET بخصوص درموقع توسعه و تست، راحتتر و سریعتر از متد POST هست. فرمانها و متغییرها و مقدار اونها رو میشه در URL براحتی دید و دستکاری کرد و نوشتن کد درخواست های GET در برنامه معمولا راحتتر و سریعتر هست (نیازی به یک فرم نداریم و یک خط آدرس بسادگی این کار رو انجام میده).

روش صحیح برای چنین اعمالی استفاده از متد POST هست. یعنی باید یک فرم داشته باشید که سابمیت بشه. حالا مثلا با کلیک بر روی یک دکمه یا هر روش دیگری.

اگر دقت کنید رفتار مرورگرها هم منطبق با استاندارد پروتکل HTTP هست.
بطور مثال وقتی شما میخواید صفحه ای رو که با متد POST فراخوانی شده رفرش کنید، مرورگر به شما پیام هشداری نشون میده مبنی بر اینکه با فراخوانی مجدد اون صفحه، اطلاعات POST شده مجددا ارسال خواهند شد و از شما بابت این کار تایید میخواد، چون ارسال مجدد این اطلاعات که به معنای ارسال مجدد یک درخواست POST هست میتونه (البته لزوما اینطور نیست) موجب تغییر وضعیت مجدد در سمت سرور بشه و شاید هدف شما از سابمیت کردن مجدد اون اطلاعات واقعا ایجاد یک تغییر جدید نبوده باشه.

——————-

من الان بخشهای مرتبط RFC رو نگاهی کردم.
الان یخورده بیشتر مطمئن شدم که متد GET کلا نباید برای درخواست هایی که موجب ایجاد تغییر در سمت سرور میشن استفاده بشه. اصلا شاید نه فقط تغییر در سمت سرور، بلکه بطور کلی هر عملیاتی که ممکنه اثر مهمی روی کاربر یا دیگران داشته باشه!
چون ظاهرا نه تنها متد Idempotent و غیر Idempotent داریم، بلکه متدهایی هم داریم که Safe تعریف شدن و متد GET جزو اونهاست.

منبع: http://tools.ietf.org/html/rfc2616#section-9.1

پاسخ دهید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

*

شما می‌توانید از این دستورات HTML استفاده کنید: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>