ارسال داده های فرم در HTML – راهنمای جامع


در این مقاله به بررسی اتفاقاتی میپردازیم که در جریان تحویل یک فرم از سوی کاربر رخ میدهد. در این نوشته بررسی خواهیم کرد که در زمان ارسال فرم HTML دادههای آن به کجا میروند و زمانی که به مقصد رسیدند چگونه میتوانیم آنها را مدیریت کنیم. همچنین به بررسی برخی دغدغههای امنیتی مرتبط با ارسال داده های فرم میپردازیم. برای مطالعه بخش قبلی این سری مطالب به لینک زیر رجوع کنید:
پیشنیاز مطالعه این نوشته سواد مقدماتی رایانه، داشتن درکی از HTML و دانش ابتدایی HTTP و همچنین برنامهنویسی سمت سرور است. هدف از این مقاله درک اتفاقاتی است که در زمان ارسال فرم رخ میدهد. بدین ترتیب ایدهای ابتدایی از شیوه پردازش دادهها در سمت سرور به دست میآوریم.
دادهها به کجا میروند؟
در این بخش بررسی میکنیم که وقتی دکمه ارسال فرم کلیک میشود، دادههای فرم HTML به کجا میروند؟
معماری کلاینت/سرور
مفهوم وب مبتنی بر یک معماری کاملاً ابتدایی کلاینت/سرور است که آن را میتوان به صورت زیر خلاصه کرد: یک کلاینت (معمولاً مرورگر وب) درخواستی را با استفاده از پروتکل HTTP به سرور (در اغلب موارد یک وبسرور مانند Apache، Nginx ،IIS ،Tomcat و غیره) ارسال میکند. سرور با استفاده از همان پروتکل به درخواست پاسخ میدهد.
در سمت کلاینت، فرم HTML چیزی به جز روشی کاربرپسند آسان برای پیکربندی یک درخواست HTTP جهت ارسال دادهها به سرور نیست. بدین ترتیب کاربر میتواند اطلاعاتی را در درخواست HTTP تحویل دهد.
تعریف کردن شیوه ارسال دادهها در سمت کلاینت
عنصر <form> شیوه ارسال دادهها را تعریف میکند. همه خصوصیتهای آن طوری طراحی شدهاند که امکان پیکربندی درخواست برای ارسال شدن در زمان کلیک روی دکمه Submit را فراهم سازند. دو مورد از مهمترین خصوصیتها action و method هستند.
خصوصیت action
این خصوصیت شیوه ارسال دادهها را تعریف میکند. مقدار آن باید یک URL معتبر باشد. اگر این خصوصیت ارائه نشده باشد، دادهها به URL صفحهای که شامل فرم است ارسال خواهند شد.
در این مثال، دادهها به یک URL مطلق یعنی (http://foo.com) ارسال میشوند:
در مثال زیر از یک URL نسبی برای ارسال دادهها به URL متفاوتی روی سرور استفاده شده است:
زمانی که مانند مثال زیر، هیچ خصوصیتی ذکر نشود، دادههای <form> به همان صفحهای ارسال میشوند که فرم در آن قرار دارد:
صفحههای قدیمیتر زیادی از نمادگذاری زیر استفاده میکنند تا نشان دهند که دادهها باید به همان صفحهای ارسال شوند که شامل فرم است. دلیل الزامی بودن این وضعیت آن است که تا HTML5 خصوصیت action الزامی بود، اما دیگر نیازی به آن ندارید.
نکته: میتوان از یک URL استفاده کرد که از پروتکل HTTPS یعنی HTTP امن بهره میگیرد. زمانی که این کار را انجام دهید، حتی اگر خود فرم روی یک صفحه ناامن میزبانی شده باشد و از طریق HTTP به آن دسترسی داشته باشید، دادهها همراه با باقی درخواست رمزنگاری میشوند. از سوی دیگر، اگر فرم روی یک صفحه امن میزبانی شده باشد، اما یک URL ناامن به صورت HTTP برای خصوصیت action وارد کنید، همه مرورگرها زمانی که کاربر دادهها را ارسال میکند، هشداری نمایش میدهند، زیرا دادهها رمزنگاری نشدهاند.
خصوصیت method
این خصوصیت شیوه ارسال شدن دادهها را تعریف میکند. پروتکل HTTP چندین روش برای اجرای درخواست ارائه میکند. دادههای فرم HTML از طریق چند روش مختلف ارسال میشوند که رایجترین آنها متد GET و متد POST هستند.
برای درک تفاوت بین دو متد فوق باید گامی به عقب برداریم و طرز کار HTTP را بررسی کنیم. هر بار که میخواهید به منبعی روی وب دسترسی پیدا کنید، مرورگر یک درخواست به آن URL ارسال میکند. هر درخواست HTTP شامل دو بخش است که یکی هدر و دیگری بدنه درخواست است. بخش هدر شامل مجموعهای از متادیتا کلی در مورد قابلیتهای مرورگر است و بخش بدنه میتواند شامل آن دسته از اطلاعات ضروری باشد که سرور برای پردازش یک درخواست خاص به آنها نیاز دارد.
متد GET
متد GET از سوی مرورگر برای درخواست از سرور جهت بازگشت دادن منبع مفروض مورد استفاده قرار میگیرد. در این حالت مرورگر یک بدنه خالی ارسال میکند. از آنجا که بدنه درخواست خالی است، اگر فرم با استفاده از این متد ارسال شود، دادههای ارسالی به سرور به URL الحاق میشوند.
فرم زیر را در نظر بگیرید:
از آنجا که متد GET مورد استفاده قرار گرفته است، میبینید که در زمان تحویل دادن فرم، URL-ای به صورت زیر در نوار آدرس مرورگر ظاهر میشود.
www.foo.com/?say=Hi&to=Mom
دادههای الحاقی به URL به صورت یک سری از جفتهای نام/مقدار هستند. پس از آن که آدرس وب URL پایان یافت یک کاراکتر علامت سؤال (?) و سپس جفتهای نام/مقدار را میآوریم که هر کدام با یک کاراکتر & از هم جدا میشوند. در این مورد، ما دو بخش از دادهها را به سرور ارسال میکنیم:
- Say که یک مقدار hi دارد.
- To که یک مقدار Mom دارد.
بدین ترتیب درخواست HTTP به صورت زیر خواهد بود:
متد POST
متد POST کمی متفاوت است. این همان متدی است که مرورگر از آن برای صحبت کردن با سرور هنگام درخواست یک پاسخ استفاده میکند. چنین درخواستی با در نظر گرفتن دادههای ارائه شده در بدنه درخواست HTTP ارسال میشود. به زبان ساده درخواست بیان میکند: «سلام سرور، به این دادهها نگاه کن و یک نتیجه مناسب به من بازگشت بده.» اگر فرم با استفاده از این متد ارسال شود، دادهها به بدنه درخواست HTTP الحاق میشوند.
زمانی که فرم با استفاده از متد POST ارسال میشود، هیچ دادهای به URL الحاق نمیشود، و درخواست HTTP نیز به صورت زیر به نظر میرسد و به جای آن دادهها در بدنه درخواست HTTP قرار میگیرند:
هدر Content-Length نشاندهنده اندازه بدنه است و هدر Content-Type نوع منابعی که به سرور ارسال میشود را نشان میدهد. در ادامه در مورد این هدرها بیشتر صحبت خواهیم کرد.
مشاهده درخواستهای HTTP
درخواستهای HTTP هرگز به کاربر نمایش پیدا نمیکنند، اگر میخواهید آنها را مشاهده کنید باید از ابزارهایی مانند Network Monitor در فایرفاکس یا Developer Tools در کروم بهره بگیرید. به عنوان مثال، دادههای فرم به صوت زیر در برگه Network کروم نمایش پیدا میکنند. پس از تحویل دادن فرم:
- دکمه F12 را بزنید.
- گزینه Network را انتخاب کنید.
- گزینه All را انتخاب کنید.
- در برگه Name گزینه foo.com را انتخاب کنید.
- گزینه Headers را انتخاب کنید.
شما میتوانید دادههای فرم را به صورتی که در تصویر زیر نمایش یافته به دست آورید:
تنها چیزی که برای کاربر نمایش پیدا میکند، URL فراخوانیشده است. چنان که پیشتر اشاره کردیم، با یک درخواست GET کاربر دادهها را در نوار URL خود میبیند، اما با درخواست POST چنین اتفاقی نمیافتد. این وضعیت به دو دلیل میتواند مهم باشد.
اگر بخواهید یک رمز عبور (یا هر داده حساس دیگر) را ارسال کنید، هرگز نباید از متد GET استفاده کنید، چون در غیر این صورت خطر نمایش یافتن آن در نوار URL وجود دارد که کاری بسیار غیر امن است.
اگر میخواهید حجم بالایی از دادهها را ارسال کنید، متد POST ترجیح دارد، زیرا، مرورگرها محدودیت اندازه URL را دارند و اغلب سرورها نیز برای پذیرش URL محدودیت تعیین کردهاند.
بازیابی دادهها در سمت سرور
هر نوع متد HTTP که انتخاب کنید، سرور رشتهای متنی دریافت خواهد کرد که آن را تجزیه میکند تا دادههایش را به صورت لیستی از جفتهای کلید/مقدار به دست آورد. روش دسترسی به این لیست به پلتفرم توسعه یا فریمورک خاصی که مورد استفاده قرار میدهید مرتبط خواهد بود. آن فناوری که استفاده میکنید روی روش مدیریت کلیدهای تکراری نیز تأثیر دارد. در اغلب موارد مقداری که اخیراً برای یک کلید، فعال بوده است ترجیح دارد.
مثال: PHP خام
PHP برخی اشیای سراسری برای دسترسی به دادهها ارائه میکند. با فرض این که از متد POST استفاده میکنید، مثال زیر صرفاً دادهها را میگیرد و آنها را به کاربر نمایش میدهد. البته این که با دادهها چه میکنید به شما مربوط است. میتوان دادهها را نمایش داد، آنها را در پایگاه داده ذخیره کرد، به وسیله ایمیل ارسال نمود یا به روش دیگری مورد پردازش قرار داد.
مثال زیر صفحهای را به همراه دادههای ارسالی نمایش میدهد. در فایل زیر روش استفاده عملی از آن را مشاهده میکنید:
فایل فوق شامل همان مثالی است که قبلاً دیدیم و دارای متد POST و یک action به صورت php-example.php است. زمانی که این فرم تحویل میشود، دادهها را به فایل php-example.php ارسال میکند که شامل کد PHP است که در قطعه کد فوق مشاهده میکنید. زمانی که این کد اجرا شود، خروجی مرورگر به صورت Hi Mom خواهد بود.
نکته: مثال فوق زمانی که صفحه را به صورت لوکال در مرورگر بارگذاری کنید کار نمیکند، زیرا مرورگرها نمیتوانند کد PHP را تفسیر کنند، بنابراین وقتی که فرم تحویل میشود، مرورگر صرفاً پیشنهاد میکند که فایل PHP را دانلود کنید. برای این که این مثال عملیاتی شود، باید آن را روی نوعی سرور PHP اجرا کنید. گزینههای مناسب برای تست PHP نرمافزارهای MAMP و AMPPS هستند.
مثال: پایتون
مثال زیر شیوه استفاده از پایتون برای انجام کاری مشابه فوق را نمایش میدهد. بدین ترتیب دادههای تحویلی در یک صفحه وب نمایش پیدا میکنند. در این مثال از فریمورک Flask برای رندر کردن قالبها، مدیریت تحویل دادهها و موارد دیگر استفاده شده است:
دو قالبی که در کد فوق مورد ارجاع قرار گرفتهاند به شرح زیر هستند:
- form.html – این همان فرمی است که قبلاً در بخش متد POST دیدیم، اما action آن روی {{ ('url_for('hello }} تنظیم شده است. در واقع این یک قالب Jinja2 است که اساساً فایل HTML است اما میتواند شامل فراخوانیهایی به کد پایتون باشد که وبسرور درون آکولادها را اجرا میکند. ('url_for('hello اعلام میکند که وقتی فرم تحویل شد، باید به آدرس hello/ ریدایرکت شود.
- greeting.html – این قالب صرفاً شامل یک خط است که دو بیت از دادههای ارسالی به آن را در زمان رندر شدن پردازش میکند. این کار از طریق تابع ()hello انجام مییابد که در بالا دیدیم و زمانی اجرا میشود که به URL با نام hello/ مراجعه کنید.
نکته: این کد نیز در صورتی که آن را مستقیماً در مرورگر بارگذاری کنید کار نخواهد کرد. طرز کار پایتون اندکی با PHP متفاوت است. برای این که بتوانید آن را به صورت لوکال اجرا کنید باید Python/PIP را نصب کنید. سپس باید Flask را با استفاده از دستور زیر نصب کنید:
pip3 install flask
در ادامه باید مثال را با استفاده از دستور زیر اجرا کنید:
python3 python-example.py
سپس به آدرس localhost:5000 در مرورگر خود بروید.
زبانها و فریمورکهای دیگر
فناوریهای سمت سرور زیاد دیگری نیز وجود دارند که میتوانید برای مدیریت فرم استفاده کنید و شامل Perl ،Java ،.Net ،Ruby و غیره هستند. شما میتوانید هر کدام را که دوست دارید انتخاب کنید. البته لازم به ذکر است که استفاده مستقیم از این فناوریها بسیار نامعمول است، زیرا کار با آنها کمی دشوار است. به طور معمول افراد از فریمورکهای خوبی مانند لیست زیر که وجود دارند استفاده میکنند تا مدیریت فرمها را به روش آسانتر انجام دهند:
- Django برای پایتون (کمی سنگینتر از Flask است، اما ابزارها و گزینههای بیشتری دارد.)
- Express برای Node.js
- Laravel برای PHP
- Ruby On Rails برای Ruby
- Phoenix برای Elixir
لازم به ذکر است که حتی در صورت استفاده از این فریمورکها نیز، کار با فرمها لزوماً آسان نیست. اما به هر حال نسبت به تلاش برای نوشتن همه کارکردها از صفر بسیار آسانتر است و صرفهجویی زمانی زیادی ایجاد میکند.
نکته: آموزش همه زبانها یا فریمورکهای سمت سرور خارج از حیطه این مقاله است.
ارسال فایل به عنوان یک حالت خاص
ارسال فایلها با استفاده از فرمهای HTML یک حالت خاص است. فایلها دادههای باینری هستند یا دست کم این گونه تصور میشوند، در حالی که همه دادههای دیگر متنی هستند. از آنجا که HTTP یک پروتکل متنی است، الزامات خاصی برای مدیریت دادههای باینری وجود دارند.
خصوصیت encrypt
این خصوصیت امکان تعیین مقدار هدر HTTP به صورت Content-Type را میدهد که در درخواست ایجاد شده هنگام تحویل فرم جای میگیرد. این هدر بسیار مهم است، زیرا به سرور اعلام میکند که چه نوع دادههایی ارسال میشوند. مقدار آن به صورت پیشفرض به صورت زیر است:
application/x-www-form-urlencoded
به زبان ساده معنای آن چنین است که: «این یک داده فرم است که به صورت پارامترهای URL کدگذاری شده است.»
اگر بخواهید فایلها را ارسال کنید، باید گامهای بیشتری بردارید:
- خصوصیت method را به صورت POST تعیین کنید، زیرا محتوای فایل نمیتواند درون پارامترهای URL قرار گیرد.
- مقدار enctype را برای multipart/form-data تعیین کنید، زیرا دادهها به بخشهای چندگانه تقسیم میشوند، که یکی برای هر فایل و دیگری برای دادههای متنی درون بدنه فرم است. این بخش دوم زمانی است که متن نیز در فرم وارد شده باشد.
- یک یا چند ویجت File picker نیز در فرم قرار میگیرد تا کاربر بتواند فایل (هایی) که میخواهد آپلود کند را انتخاب نماید.
برای نمونه:
نکته: برخی مرورگرها از خصوصیت multiple روی عنصر <input> پشتیبانی میکنند و بدین ترتیب میتوانید بیش از یک فایل را به وسیله تنها یک عنصر <input> برای آپلود انتخاب کنید. این که سرور چگونه این فایلها را در عمل مدیریت میکند، به فناوری مورد استفاده در سمت سرور بستگی دارد. چنان که پیشتر گفتیم، استفاده از یک فریمورک موجب میشود که کارها بسیار آسانتر شوند.
هشدار: بسیاری از سرورها با محدودیت اندازه برای فایلها و درخواستهای HTTP پیکربندی شدهاند تا از سوءاستفادههای احتمالی جلوگیری کنند. پیش از ارسال یک فایل، این محدودیت را با مدیر سرور بررسی کنید.
دغدغههای رایج امنیتی
هر بار که دادهها را به سرور ارسال میکنید، باید بحث امنیت را در نظر داشته باشید. فرمهای HTML با اختلاف زیاد یکی از مهمترین هدفهای حملات رایج به سرورها هستند. البته این مشکلات هرگز از خود فرمهای HTML ناشی نمیشوند، بلکه ناشی از شیوه مدیریت دادهها از سوی سرور هستند.
بسته به این که میخواهد چه کار بکنید، برخی مشکلات کاملاً شناختهشده امنیتی وجود دارند که ممکن است با آنها مواجه شوید:
XSS و CSRF
اسکریپتنویسی بین سایت (XSS) و جعل درخواست بین سایت (CSRF) دو نوع رایج از حملههایی هستند که در زمان نمایش دادههای ارسالی یک کاربر به کاربر دیگر رخ میدهند.
حمله XSS به مهاجم امکان میدهد که اسکریپتهای سمت کلاینت را در صفحههای وب مشاهدهشده از سوی کاربران دیگر تزریق کند. آسیبپذیری اسکریپتنویسی بین سایت از سوی مهاجمان برای دور زدن کنترلهایی مانند «سیاست ریشه یکسان» (same origin policy) را فراهم میسازد. تأثیر این حملهها متفاوت است و از یک مزاحمت ساده تا ریسکهای امنیتی مهم متغیر خواهد بود.
حملههای CSRF مشابه حملههای XSS هستند، چون به روش مشابهی آغاز میشوند و اسکریپت سمت کلاینت در صفحههای وب تزریق میشود، اما هدف آنها متفاوت است. مهاجمان CSRF تلاش میکنند تا دسترسیهای مربوط به کاربران با دسترسی بالاتر (مانند مدیر سایت) را به دست آورند تا اقداماتی را که نباید انجام دهند به اجرا درآورند. برای مثال بدین ترتیب میتوانند دادهها را به یک کاربر غیر معتمد ارسال کنند.
حملههای XSS از اعتمادی که یک کاربر به وبسایت دارد سوءاستفاده میکنند، در حالی که حملههای CSRF از اعتمادی که وبسایت به کاربران خود دارد سوءاستفاده میکنند.
برای جلوگیری از این حملهها، باید همواره دادههایی که یک کاربر به سرور ارسال میکند (در صورت نیاز به نمایش دادن) را بررسی کنید و تلاش کنید محتوای HTML ارائهشده از سوی کاربر را نمایش ندهید. به جای آن باید دادههای ارائهشده از سوی کاربر را پردازش کنید تا به صورت خام نمایش پیدا نکند. تقریباً همه فریمورکهای موجود امروزه یک فیلتر کمینه پیادهسازی کردهاند که عناصر <script> ،<iframe> و <object> مربوط به HTML را از دادههای ارسالی از سوی هر کاربر حذف میکنند. بدین ترتیب ریسک کاهش پیدا میکند، اما لزوماً رفع نمیشود.
تزریق SQL
تزریق SQL نوعی از حمله است که در آن مهاجم تلاش میکند اقدامی را روی یک پایگاه داده مورد استفاده از سوی وبسایت هدف اجرا نماید. این نوع حمله عموماً شامل ارسال یک درخواست SQL به امید اجرا شدن آن از سوی سرور است. این اتفاق معمولاً زمانی رخ میدهد که سرور اپلیکیشن تلاش میکند دادههای ارسالی از سوی کاربر را در پایگاه داده ذخیره کند. در واقع این نوع حمله یکی از اصلیترین نوع حملات در برابر وبسایتها محسوب میشود.
عواقب چنین حملاتی میتواند فاجعهآمیز باشد و از فقدان دادهها تا حملاتی برای به دست آوردن کنترل زیرساخت وبسایت از طریق کسب دسترسیهای مورد نیاز متفاوت است. این یک تهدید بسیار جدی است و شما هرگز نباید دادههای ارسالی از سوی کاربر را بدون اجرای نوعی مراحل پاکسازی در پایگاه داده ذخیره کنید.
تزریق هدر HTTP و تزریق ایمیل
این نوع از حملهها زمانی رخ میدهند که اپلیکیشن هدرهای HTTP یا ایمیلها را بر مبنای دادههای وارد شده از سوی کاربر در یک فرم میسازد. این حمله به صوت مستقیم به سرور شما آسیب نمیزند و کاربران را نیز متأثر نمیسازد، اما یک درِ باز برای مشکلات عمیقتری مانند سرقت «نشست» (Session) یا حملههای فیشینگ فراهم میکند.
این نوع حملهها عموماً خاموش هستند و میتوانند سرور شما را به یک زامبی تبدیل کنند.
همیشه مشکوک باشید و به کاربرانتان اعتماد نکنید
اینک سؤال این است که چگونه میتوان با این تهدیدها مبارزه کرد؟ پاسخ دادن به این سؤال نیاز به یک راهنمای کاملاً مفصلی دارد، اما به طور خلاصه چند قاعده وجود دارد که باید در ذهن خود داشته باشید. مهمترین قاعده این است که هرگز به کاربرانتان که شامل خود شما نیز میشود اعتماد نکنید. حتی یک کاربر معتمد هم میتواند به سرقت رفته باشد.
همه دادههایی که به سرور میآیند باید بررسی و پاکسازی شوند. هیچ استثنایی در این خصوص وجود ندارد.
- کاراکترهای بالقوه خطرناک را escape کنید. در مورد کاراکترهای خاص باید با احتیاط رفتار کنید، زیرا بستگی زیادی به زمینه کاربرد دادهها و پلتفرم سروری که استفاده میکنید دارد، اما همه زبانهای سمت سرور، تابعهایی به این منظور دارند.
- مقدار دادههای مجاز ورودی را صرفاً محدود به مقدار مورد نیاز بکنید.
- فایلهای آپلود شده را در محیط ایزوله (Sandbox) نگهداری کنید. به این منظور باید فایلها را روی یک سرور مجزا نگهداری کنید و تنها از طریق زیردامنه متفاوت و یا بهتر از آن از طریق نام دامنه کاملاً متفاوت امکان دسترسی به آن را فراهم سازید.
با پیروی از سه قاعده فوق از بسیاری از مشکلات امنیتی که ممکن است پیش آید جلوگیری میکنید، اما اجرای یک بررسی امنیتی از سوی شخص ثالث همواره ایده خوبی تلقی میشود. همواره این را در نظر داشته باشید که شما شخصاً نمیتوانید همه مشکلات بالقوه را ببینید.
سخن پایانی
چنان که مشاهده کردید، ارسال دادههای فرم کار آسانی است، اما امن سازی یک اپلیکیشن چنین نیست. کافی است به خاطر بسپارید که یک توسعهدهنده فرانتاند تنها کسی نیست که مدل امنیتی دادهها را تعریف میکند. چنان که در این مقاله دیدیم امکان اجرای اعتبارسنجی دادهها در سمت کلاینت وجود دارد، اما سرور نمیتواند به این اعتبارسنجی اعتماد کند، زیرا هیچ راهی برای دانستن این که در سمت کلاینت چه اتفاقی رخ داده است ندارد.
برای مطالعه بخش بعدی این مجموعه مقالات آموزشی به لینک زیر مراجعه کنید:
اگر این مطلب برای شما مفید بوده است، آموزشهای زیر نیز به شما پیشنهاد میشوند:
- مجموعه آموزش طراحی سایت با HTML و CSS
- آموزش پروژه محور HTML و CSS
- مجموعه آموزشهای برنامهنویسی
- ۵ گام برای درک کدهای پایه HTML – آموزش مقدماتی
- مبانی کار با متن در HTML — راهنمای کاربردی
==
با عرض سلام … ببخشید من فرمم رو با html , css , js طراحی کردم و فایل email.php رو هم اماده کردم فقط یه سوال این ها رو باید کجا قرار بدم ک اجرا بشن ؟
1- فایل های طراحی که هیج این ها در یک برگه است سایت است
*** فایل email.php رو کجا بزارم ؟ تو هاست ؟ کجا ؟؟
خواهشا راهنمایی بفرمایید خیلی تحقیق کردم موفق نشدم ..
سلام.ببخشید میخواستم در سایتم ارسال نظر کاربر داشته باشم مثل اینیکه شما گذاشتید و ما میتونیم نظر خودمونو بزاریم.میشه لطفا توضیح بدید چطوری میشه این کار رو انجام داد؟
ممنون.
سلام اگه بخوام یه input داشته باشم از نوع تکست که چیزی که کاربر مینویسه زیرش نمایش داده بشه .و بعد دوباره تو همون input چیزدیگری نوشت نمایش تکست قبلی پاک نشه و زیر هم نشون داده بشه چیکار کنم؟
سلام دوست عزیز.
واقعا متاسفم ولی علیرغم این که چند بار سوالتان رو خواندم متوجه منظورتان نشدم.