مهندس موفق الکترونیک

برنامه‌نویسی وب در ++C

CGI چیست؟

  • رابط دروازه مشترک (Common Gate interface) یا CGI، مجموعه‌ای از استانداردها می‌باشد که چگونگی ردوبدل کردن اطلاعات بین سرور و یک اسکریپت دلخواه را تعریف می‌کند.
  • مشخصات فعلی CGI توسط NCSA نگه‌داری می‌شود.CGI ،NCSA را به صورت زیر تعریف می‌کند.
  • رابط دروازه مشترک، استانداردی برای دروازه خروجی برنامه به رابط سرور اطلاعاتی مانند سرورهای HTTP می‌باشد.
  • نسخه فعلی CGI/1.1 است و نسخه CGI/1.2 تحت توسعه می‌باشد.

مرورگر وب (Web Browsing)

برای درک مفهوم CGI، اجازه دهید که بررسی کنیم با کلیک کردن روی یک لینک در مرورگر چه اتفاقی خواهد افتاد.

  • مرورگر شما با سرور HTTP وب تماس حاصل کرده و برای یک URL،مثلاً یک فایل، درخواست ارسال می‌کند.
  • سرور وب URL را تجزیه (parse) کرده و به دنبال نام فایل می‌گردد. اگر نام فایل درخواستی را پیدا کند، آن را به مرورگر ارسال خواهد کرد و در غیراین صورت یک پیام خطا مبنی بر اینکه فایل درخواست شده اشتباه است فرستاده می‌شود.
  • مرورگر وب پاسخ را از وب سرور گرفته و بسته به پیام رسیده، فایل و یا پیغام خطا را نمایش خواهد داد.

با این‌حال، می‌توان سرور HTTP را به گونه‌ای تنظیم کرد که هر زمان که درخواست یک فایل از پوشه مشخص ارسال شود، آن فایل مستقیماً برگردانده نشود؛ در عوض، فایل به عنوان یک برنامه اجرا شده و خروجی حاصل از آن به مرورگر فرستاده شود.

رابط دروازه مشترک یک پروتکل استاندارد برای توانمندسازی برنامه‌ها (برنامه‌های CGI یا اسکریپت‌های CGI) برای تعامل با کلاینت‌ها (Client) و وب سرورها می‌باشد. این برنامه‌های CGI را می‌توان به زبان‌های Python، PERL ، Shell، C یا ++C و… نوشت.

دیاگرام معماری CGI

دیاگرام ساده‌ی زیر معماری اولیه CGI را نشان می‌دهد.

برنامه‌نویسی وب در ++C

پیکربندی وب سرور (Web Server Configuration)

قبل از اینکه برنامه‌نویسی CGI را به پیش ببریم، باید اطمینان حاصل کنیم که وب سرور ما از CGI پشتیبانی کرده و برای رسیدگی به برنامه‌های CGI پیکربندی شده است. همه‌ی برنامه‌های CGI روی سرور HTTP در یک پوشه از پیش تعیین شده نگه‌داری می‌شوند. این پوشه CGI نامیده شده و به صورت قراردادی نامی‌ به صورت «var/www/cgi-bin/» دارد. فایل‌های CGI، بااینکه فایل‌های اجرایی ++C می‌باشند، اما به صورت قراردادی پسوند cgi. دارند.

به صورت پیش‌فرض، وب سرور Apache برای اجرای برنامه‌های CGI در «var/www/cgi-bin/» پیکربندی شده است. اگر بخواهید پوشه دیگری را برای اجرای اسکریپت‌های CGI مشخص کنید، باید فایل httpd.conf را به صورت زیر ویرایش کنید.

<Directory "/var/www/cgi-bin">
   AllowOverride None
   Options ExecCGI
   Order allow,deny
   Allow from all
</Directory>
 
<Directory "/var/www/cgi-bin">
   Options All
</Directory>

در اینجا، فرض را بر این می‌گذاریم که وب سرور شما در حال فعالیت بوده و شما قادر به اجرای دیگر برنامه‌های CGI مانند Perl یا Shell و… هستید.

اولین برنامه CGI

برنامه ++C زیر را درنظر بگیرید.

#include <iostream>
using namespace std;

int main () {
   cout << "Content-type:text/html\r\n\r\n";
   cout << "<html>\n";
   cout << "<head>\n";
   cout << "<title>Hello World - First CGI Program</title>\n";
   cout << "</head>\n";
   cout << "<body>\n";
   cout << "<h2>Hello World! This is my first CGI program</h2>\n";
   cout << "</body>\n";
   cout << "</html>\n";
   
   return 0;
}

فایل بالا را کامپایل کرده و نام فایل اجرایی را به «cplusplus.cgi» تغییر دهید. این فایل در پوشه «var/www/cgi-bin/» ذخیره شده و داری محتویات زیر است. قبل از اجرای برنامه CGI خود، مطئمن شوید که مد فایل را با استفاده از دستور یونیکس «chmod 755 cplusplus.cgi» به حالت اجرایی تغییر داده‌اید.

اولین برنامه CGI من

برنامه ++C فوق، یک برنامه ساده بوده که خروجی‌اش را روی فایل STDOUT، یعنی صفحه نمایش می‌نویسد. در خط اول برنامه، یک ویژگی مهم ، یعنی چاپ «Content-type: text/html\r\n\r\n» وجود دارد. این خط به مرورگر برگرانده می‌شود و نوع محتوای ارسالی برای نمایش در صفحه‌ی مرورگر را مشخص می‌کند. اکنون انتظار می‌رود که مفاهیم پایه ای CGI را درک کرده باشید و بتوانید برنامه‌های CGI پیچیده‌ای با پایتون بنویسید. یک برنامه CGI برای ردوبدل کردن اطلاعات، قادر به تعامل با سیستم‌های خارجی مانند RDBMS می‌باشد.

سربرگ HTTP یا HTTP Header

خط «Content-type: text/html\r\n\r\n» بخشی از سربرگ header می‌باشد، که برای فهماندن محتوا به مرورگر ارسال می‌گردد. همه سربرگ‌های HTTP شکل زیر را دارند.

HTTP Field Name: Field Content
 
For Example
Content-type: text/html\r\n\r\n

چند سربرگ HTTP مهم وجود دارند که در برنامه‌نویسی CGI مکرراً استفاده می‌شوند.

ردیف

سربرگ و توصیف آن

1

Content-type

یک رشته MIME که فرمت فایل بازگشتی را تعریف می‌کند. مثال Content-type: text/html

2

Expires: Date

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

یک رشته معتبر باید در قالب 01Jan 1998 12:00:00 GMT باشد.

3

Location: URL

URLای که به جای URL درخواست شده برگردانده می‌شود. از این فیلد می‌توان برای ارجاع (redirect) هر فایل درخواستی استفاده کرد.

4

Last-modified: Date

این فیلد دربردارنده زمان آخرین ویرایش منبع می‌باشد.

5

Content-length: N

این فیلد حاوی طول فایل بازگشتی در واحد بایت می‌باشد. مرورگر از این مقدار برای تخمین زمان دانلود فایل استفاده می‌کند.

6

Set-Cookie: String

کوکی (cookie) را در قالب یک رشته برمی‌گرداند.

متغیرهای محیطی CGI

همه برنامه‌های CGI به متغیرهای محیطی دسترسی خواهند داشت. این متغیرهای محیطی نقش مهمی ‌در نوشتن برنامه‌های CGI بازی می‌کنند.

ردیف

متغیرهای محیطی و توصیف آن

1

CONTENT_TYPE

نوع داده‌ی محتوا، زمانی استفاده می‌شود که کلاینت یک فایل ضمیمه به سرور ارسال کند. برای مثال، آپلود یک فایل.

2

CONTENT_LENGTH

طول اطلاعات کوئری (query) که تنها در درخواست‌های POST موجود هستند.

3

HTTP_COOKIE

کوکی‌های تنظیم شده را در قالب زوج کلید و مقدار (key&value) برمی‌گرداند.

4

HTTP_USER_AGENT

فیلد User-Agent از هدر درخواست، که حاوی اطلاعاتی درباره‌ی کاربری است که درخواست از جانب او صادر شده است. در واقع نامی ‌از وب سرور می‌باشد.

5

PATH_INFO

مسیر اسکریپت CGI

6

QUERY_STRING

اطلاعات انکد شده URL که به همراه متد درخواست GET ارسال می‌شود.

7

REMOTE_ADDR

آدرس IP میزبان راه دور (remote host) که درخواست را ایجاد کرده است. این فیلد برای اهداف logging یا احراز هویت (authentication) مفید است.

8

REMOTE_HOST

نام کامل میزبان ایجادکننده درخواست. اگراین فیلد موجود نباشد، آنگاه می‌توان از REMOTE_ADDR برای گرفتن آدرس IP استفاده کرد.

9

REQUEST_METHOD

متدی که برای ایجاد درخواست به کار رفته است. متداول ترین متدها GET و POST می‌باشند.

10

SCRIPT_FILENAME

مسیر کامل به اسکریپت CGI

11

SCRIPT_NAME

نام اسکریپت CGI

12

SERVER_NAME

Hostname سرور یا آدرس IP آن

13

SERVER_SOFTWARE

نام و نسخه نرم افزاری که روی سرور در حال اجرا است.

برنامه CGI زیر همه متغیرهای CGI را لیست می‌کند.

#include <iostream>
#include <stdlib.h>
using namespace std;

const string ENV[ 24 ] = {
   "COMSPEC", "DOCUMENT_ROOT", "GATEWAY_INTERFACE",   
   "HTTP_ACCEPT", "HTTP_ACCEPT_ENCODING",             
   "HTTP_ACCEPT_LANGUAGE", "HTTP_CONNECTION",         
   "HTTP_HOST", "HTTP_USER_AGENT", "PATH",            
   "QUERY_STRING", "REMOTE_ADDR", "REMOTE_PORT",      
   "REQUEST_METHOD", "REQUEST_URI", "SCRIPT_FILENAME",
   "SCRIPT_NAME", "SERVER_ADDR", "SERVER_ADMIN",      
   "SERVER_NAME","SERVER_PORT","SERVER_PROTOCOL",     
   "SERVER_SIGNATURE","SERVER_SOFTWARE" };   

int main () {
   cout << "Content-type:text/html\r\n\r\n";
   cout << "<html>\n";
   cout << "<head>\n";
   cout << "<title>CGI Environment Variables</title>\n";
   cout << "</head>\n";
   cout << "<body>\n";
   cout << "<table border = \"0\" cellspacing = \"2\">";

   for ( int i = 0; i < 24; i++ ) {
      cout << "<tr><td>" << ENV[ i ] << "</td><td>";
      
      // attempt to retrieve value of environment variable
      char *value = getenv( ENV[ i ].c_str() );  
      if ( value != 0 ) {
         cout << value;                                 
      } else {
         cout << "Environment variable does not exist.";
      }
      cout << "</td></tr>\n";
   }
   
   cout << "</table><\n";
   cout << "</body>\n";
   cout << "</html>\n";
   
   return 0;
}

کتابخانه CGI در ++ C

در مثال‌های واقعی، شما باید کارهای زیادی را در برنامه CGI خود انجام دهید. یک کتابخانه CGI برای ++C نوشته شده که می‌توان آن را از آدرس ftp://ftp.gnu.org/gnu/cgicc دانلود کرده و طبق دستورات زیر نصب کنید.

$tar xzf cgicc-X.X.X.tar.gz 
$cd cgicc-X.X.X/ 
$./configure --prefix=/usr 
$make
$make install

می‌توان مستندات (Documentation) مربوطه را از C++ CGI Lib Documentation مشاهده کرد.

متدهای POST و GET

احتمالاً برای شما موقعیت‌های زیادی پیش آمده که نیاز به ارسال اطلاعات از مرورگر به وب سرور و نهایتاً برنامه CGI داشته‌اید. بیشتر مرورگرها از دو متد برای ارسال اطلاعات به وب سرورها استفاده می‌کنند. این متدها GET و POST هستند.

ارسال اطلاعات با متد GET

متد GET اطلاعات انکد شده کاربر که به انتهای درخواست صفحه افزوده شده است را ارسال می‌کند. صفحه و اطلاعات انکد شده با کارکتر «؟» از هم جدا می‌شوند.

http://www.test.com/cgi-bin/cpp.cgi?key1=value1&key2=value2

متد GET متد پیش‌فرض برای ارسال اطلاعات از مرورگر به سرور می‌باشد که منجر به تولید یک رشته‌ی بلند در نوار آدرس (location box) مرورگر شما خواهد شد. اگر کلمه عبور یا هر اطلاعات حساس دیگری برای ارسال به سرور دارید، هرگز از متد GET استفاده نکنید. متد GET با محدودیت اندازه مواجه بوده و در هر رشته درخواست تنها مجاز به استفاده تا 1024 بایت می‌باشد.

هنگام استفاده از متد GET، اطلاعات با استفاده از سربرگ «QUERY_STRING» ارسال می‌شوند و در برنامه CGI از طریق متغیر محیطی «QUERY_STRING» قابل دسترسی می‌باشد.

اطلاعات را می‌توان با چسباندن زوج کلید و مقدار در کنار هر URL یا برچسب‌های HTML FORM از طریق متد GET ارسال کرد.

مثال ساده URL: متد GET

در زیر یک مثال ساده از URLای که با متد GET دو مقدار به برنامه «hello_get.py» ارسال می‌کند آمده است.

/cgi-bin/cpp_get.cgi?first_name=ZARA&last_name=ALI

برنامه‌ی زیر «cpp_get.cgi» برای رسیدگی به داده‌های ورودی از مرورگر وب نوشته شده است. می‌خواهیم از کتابخانه CGI در ++C استفاده کنیم تا دسترسی به این اطلاعات ساده‌تر شود.

#include <iostream>
#include <vector>  
#include <string>  
#include <stdio.h>  
#include <stdlib.h> 

#include <cgicc/CgiDefs.h> 
#include <cgicc/Cgicc.h> 
#include <cgicc/HTTPHTMLHeader.h> 
#include <cgicc/HTMLClasses.h>  

using namespace std;
using namespace cgicc;

int main () {
   Cgicc formData;
   
   cout << "Content-type:text/html\r\n\r\n";
   cout << "<html>\n";
   cout << "<head>\n";
   cout << "<title>Using GET and POST Methods</title>\n";
   cout << "</head>\n";
   cout << "<body>\n";

   form_iterator fi = formData.getElement("first_name");  
   if( !fi->isEmpty() && fi != (*formData).end()) {  
      cout << "First name: " << **fi << endl;  
   } else {
      cout << "No text entered for first name" << endl;  
   }
   
   cout << "<br/>\n";
   fi = formData.getElement("last_name");  
   if( !fi->isEmpty() &&fi != (*formData).end()) {  
      cout << "Last name: " << **fi << endl;  
   } else {
      cout << "No text entered for last name" << endl;  
   }
   
   cout << "<br/>\n";
   cout << "</body>\n";
   cout << "</html>\n";
   
   return 0;
}

حال برنامه را به صورت زیر کامپایل کنید.

$g++ -o cpp_get.cgi cpp_get.cpp -lcgicc

فایل «cpp_get.cgi» را تولید کرده و آن را در پوشه‌ی CGI قرار دهید و با استفاده از لینک زیر سعی کنید که به آن دسترسی پیدا کنید.

/cgi-bin/cpp_get.cgi?first_name=ZARA&last_name=ALI

باید خروجی زیر را مشاهده کنید.

First name: ZARA 
Last name: ALI 

مثال ساده FORM: متد GET

در زیر مثالی ساده آمده که با استفاده از HTML FORM و دکمه Submit دو مقدار را ارسال می‌کند. می‌خواهیم از همان اسکریپت CGI برای رسیدگی به این ورودی‌ها استفاده کنیم.

<form action = "/cgi-bin/cpp_get.cgi" method = "get">
   First Name: <input type = "text" name = "first_name">  <br />
 
   Last Name: <input type = "text" name = "last_name" />
   <input type = "submit" value = "Submit" />
</form>

خروجی کد فوق در زیر نشان داده شده است. First Name و Last Name را وارد کرده وسپس دکمه Submit را بزنید تا نتیجه را مشاهده کنید.

برنامه‌نویسی وب در ++C

ارسال اطلاعات با متد POST

متد POST متد نسبتاً پایدارتری برای ارسال اطلاعات به یک برنامه CGI می‌باشد. این متد اطلاعات را به همان روش متد GET بسته‌بندی می‌کند، اما به جای ارسال آن به صورت یک رشته متنی پس از ؟ در URL، آن را به صورت یک پیام جداگانه می‌فرستد. این پیام در قالب یک ورودی استاندارد وارد اسکریپت CGI می‌شود.

همان برنامه «cpp_get.cgi» برای متد POST نیز به کار می‌رود. اجازه دهید همان مثال قبلی را، که در آن دو مقدار را با استفاده از فرم HTML و دکمه submit ارسال کردیم مجدداً به کار ببریم.

<form action = "/cgi-bin/cpp_get.cgi" method = "post">
   First Name: <input type = "text" name = "first_name"><br />
   Last Name: <input type = "text" name = "last_name" />
 
   <input type = "submit" value = "Submit" />
</form>

خروجی کد فوق در زیر نشان داده شده است. First Name و Last Name را وارد کرده وسپس دکمه Submit را بزنید تا نتیجه را مشاهده کنید.

برنامه‌نویسی وب در ++C

ارسال داده جعبه تیک‌دار (Checkbox) به برنامه CGI

زمانی‌که از بین گزینه‌های موجود، انتخاب بیش از یک گزینه مد نظر باشد، از جعبه‌های تیک‌دار استفاده می‌شود.

کد HTML زیر یک فرم با دو جعبه تیک‌دار را ایجاد می‌کند

<form action = "/cgi-bin/cpp_checkbox.cgi" method = "POST" target = "_blank">
   <input type = "checkbox" name = "maths" value = "on" /> Maths
   <input type = "checkbox" name = "physics" value = "on" /> Physics
   <input type = "submit" value = "Select Subject" />
</form>

نتیجه این کد به صورت زیر خواهد بود.

برنامه ++C زیر، اسکریپت «cpp_checkbox.cgi» را برای رسیدگی به داده‌های ورودی از جعبه‌های تیک‌دار تولید می‌کند.

#include <iostream>
#include <vector>  
#include <string>  
#include <stdio.h>  
#include <stdlib.h> 

#include <cgicc/CgiDefs.h> 
#include <cgicc/Cgicc.h> 
#include <cgicc/HTTPHTMLHeader.h> 
#include <cgicc/HTMLClasses.h> 

using namespace std;
using namespace cgicc;

int main () {
   Cgicc formData;
   bool maths_flag, physics_flag;

   cout << "Content-type:text/html\r\n\r\n";
   cout << "<html>\n";
   cout << "<head>\n";
   cout << "<title>Checkbox Data to CGI</title>\n";
   cout << "</head>\n";
   cout << "<body>\n";

   maths_flag = formData.queryCheckbox("maths");
   if( maths_flag ) {  
      cout << "Maths Flag: ON " << endl;  
   } else {
      cout << "Maths Flag: OFF " << endl;  
   }
   cout << "<br/>\n";

   physics_flag = formData.queryCheckbox("physics");
   if( physics_flag ) {  
      cout << "Physics Flag: ON " << endl;  
   } else {
      cout << "Physics Flag: OFF " << endl;  
   }
   
   cout << "<br/>\n";
   cout << "</body>\n";
   cout << "</html>\n";
   
   return 0;
}

ارسال داده از دکمه‌های رادیویی (Radio Button) به برنامه CGI

دکمه‌های رادیویی در جاهایی کاربرد دارند که تنها باید یک گزینه از میان سایر گزینه‌ها انتخاب شود.

کد زیر یک فرم HTML با دو دکمه رادیویی می‌سازد.

<form action = "/cgi-bin/cpp_radiobutton.cgi" method = "post" target = "_blank">
   <input type = "radio" name = "subject" value = "maths" checked = "checked"/> Maths 
   <input type = "radio" name = "subject" value = "physics" /> Physics
   <input type = "submit" value = "Select Subject" />
</form>

خروجی کد به این شکل خواهد بود.

برنامه‌نویسی وب در ++C

برنامه ++C زیر، اسکریپت «cpp_radiobutton.cgi» را تولید می‌کند که به داده‌های ورودی از دکمه‌های رادیویی رسیدگی می‌کند.

#include <iostream>
#include <vector>  
#include <string>  
#include <stdio.h>  
#include <stdlib.h> 

#include <cgicc/CgiDefs.h> 
#include <cgicc/Cgicc.h> 
#include <cgicc/HTTPHTMLHeader.h> 
#include <cgicc/HTMLClasses.h> 

using namespace std;
using namespace cgicc;

int main () {
   Cgicc formData;
  
   cout << "Content-type:text/html\r\n\r\n";
   cout << "<html>\n";
   cout << "<head>\n";
   cout << "<title>Radio Button Data to CGI</title>\n";
   cout << "</head>\n";
   cout << "<body>\n";

   form_iterator fi = formData.getElement("subject");  
   if( !fi->isEmpty() && fi != (*formData).end()) {  
      cout << "Radio box selected: " << **fi << endl;  
   }
  
   cout << "<br/>\n";
   cout << "</body>\n";
   cout << "</html>\n";
   
   return 0;
}

ارسال داده‌های text area به برنامه CGI

TEXTAREA عنصری است که برای ارسال متن چند خطه به برنامه CGI به کار می‌رود.

کد زیر یک فرم HTML با یک جعبه TEXTAREA می‌سازد.

<form action = "/cgi-bin/cpp_textarea.cgi" method = "post" target = "_blank">
   <textarea name = "textcontent" cols = "40" rows = "4">
      Type your text here...
   </textarea>
   <input type = "submit" value = "Submit" />
</form>

خروجی کد به شکل زیر خواهد بود.

برنامه‌نویسی وب در ++C

برنامه‌ی ++C زیر یک اسکریپت به نام «cpp_textarea.cgi» تولید می‌کند که داده ورودی از textarea را مدیریت می‌کند.

#include <iostream>
#include <vector>  
#include <string>  
#include <stdio.h>  
#include <stdlib.h> 

#include <cgicc/CgiDefs.h> 
#include <cgicc/Cgicc.h> 
#include <cgicc/HTTPHTMLHeader.h> 
#include <cgicc/HTMLClasses.h> 

using namespace std;
using namespace cgicc;

int main () {
   Cgicc formData;
  
   cout << "Content-type:text/html\r\n\r\n";
   cout << "<html>\n";
   cout << "<head>\n";
   cout << "<title>Text Area Data to CGI</title>\n";
   cout << "</head>\n";
   cout << "<body>\n";

   form_iterator fi = formData.getElement("textcontent");  
   if( !fi->isEmpty() && fi != (*formData).end()) {  
      cout << "Text Content: " << **fi << endl;  
   } else {
      cout << "No text entered" << endl;  
   }
  
   cout << "<br/>\n";
   cout << "</body>\n";
   cout << "</html>\n";
   
   return 0;
}

ارسال داده از جعبه کشویی (Drop down Box) به برنامه CGI

جعبه کشویی زمانی استفاده می‌شود که چندین گزینه در دسترس وجود دارد اما تنها یک یا دو گزینه از آنها قابل انتخاب است.

کد زیر یک فرم HTML با یک جعبه کشویی تولید می‌کند.

<form action = "/cgi-bin/cpp_dropdown.cgi" method = "post" target = "_blank">
   <select name = "dropdown">
      <option value = "Maths" selected>Maths</option>
      <option value = "Physics">Physics</option>
   </select>
   
   <input type = "submit" value = "Submit"/>
</form>

خروجی این کد به صورت زیر خواهد بود.

برنامه‌نویسی وب در ++C

برنامه ++C زیر یک اسکریپت به نام «cpp_dropdown.cgi» تولید می‌کند که داده ورودی از لیست کشویی را مدیریت می‌کند.

#include <iostream>
#include <vector>  
#include <string>  
#include <stdio.h>  
#include <stdlib.h> 

#include <cgicc/CgiDefs.h> 
#include <cgicc/Cgicc.h> 
#include <cgicc/HTTPHTMLHeader.h> 
#include <cgicc/HTMLClasses.h> 

using namespace std;
using namespace cgicc;

int main () {
   Cgicc formData;
  
   cout << "Content-type:text/html\r\n\r\n";
   cout << "<html>\n";
   cout << "<head>\n";
   cout << "<title>Drop Down Box Data to CGI</title>\n";
   cout << "</head>\n";
   cout << "<body>\n";

   form_iterator fi = formData.getElement("dropdown");  
   if( !fi->isEmpty() && fi != (*formData).end()) {  
      cout << "Value Selected: " << **fi << endl;  
   }
  
   cout << "<br/>\n";
   cout << "</body>\n";
   cout << "</html>\n";
   
   return 0;
}

کاربرد کوکی‌ها در CGI

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

در بسیاری از موارد، استفاده از کوکی‌ها موثرترین روش برای ردیابی تنظیمات، خریدها، اعمال و دیگر اطلاعات مورد نیاز برای تجربه بهتر بازدید یا اطلاعات آماری سایت می‌باشد.

نحوه عملکرد

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

کوکی‌ها رکوردهای متنی با 5 فیلد طول متغیر می‌باشند.

  • Expires: این فیلد زمان انقضای کوکی را نمایش می‌دهد. اگر خالی باشد، کوکی با خروج بازدید کننده از مرورگر از بین خواهد رفت.
  • Domain: این فیلد نام دامنه سایت شما را نمایش می‌دهد.
  • Path: این فیلد مسیر یا صفحه وب تنظیم کننده کوکی را نشان می‌دهد. اگر بخواهید که کوکی همه صفحه‌ها یا پوشه‌ها را بازیابی کند، این فیلد باید خالی باشد.
  • Secure: اگر این فیلد حاوی واژه secure باشد، آنگاه کوکی تنها از طریق یک سرور امن قابل بازیابی است. اگر فیلد خالی باشد، هیچ محدودیتی وجود نخواهد داشت.
  • Name = Value: کوکی‌ها به صورت زوج‌های کلید و مقدار تنظیم و بازیابی می‌شوند.

تنظیم کوکی‌ها

ارسال کوکی‌ها به مرورگر بسیار ساده است. این کوکی‌ها همراه با سربرگ‌های HTTP و قبل از فیلد «Content-type» ارسال می‌شوند. فرض کنید که بخواهید یک UserID و Password را به عنوان کوکی ارسال کنید. تنظیمات کوکی به شیوه‌ی زیر صورت می‌گیرد.

#include <iostream>
using namespace std;

int main () {
   cout << "Set-Cookie:UserID = XYZ;\r\n";
   cout << "Set-Cookie:Password = XYZ123;\r\n";
   cout << "Set-Cookie:Domain = www.tutorialspoint.com;\r\n";
   cout << "Set-Cookie:Path = /perl;\n";
   cout << "Content-type:text/html\r\n\r\n";

   cout << "<html>\n";
   cout << "<head>\n";
   cout << "<title>Cookies in CGI</title>\n";
   cout << "</head>\n";
   cout << "<body>\n";

   cout << "Setting cookies" << endl;  
  
   cout << "<br/>\n";
   cout << "</body>\n";
   cout << "</html>\n";
   
   return 0;
}

پس از این مثال، حالا باید با نحوه تنظیم کوکی‌ها آشنا شده باشید. از سربرگ «Set-Cookie» برای تنظیم کوکی‌ها استفاده می‌کنیم.

تنظیم خصوصیات کوکی‌ها مانند Expires، Domain و Path اختیاری است. دقت کنید که کوکی‌ها قبل از ارسال خط «Content-type:text/html\r\n\r\n» تنظیم می‌شوند.

برنامه فوق را کامپایل کرده تا فایل «setcookies.cgi» تولید شود، و سعی کنید که با استفاده از لینک زیر کوکی‌ها را تنظیم کنید.این لینک چهار کوکی در کامپیوتر شما تنظیم می‌کند.

/cgi-bin/setcookies.cgi

بازیابی کوکی‌ها

بازیابی همه کوکی‌ها آسان است. کوکی‌ها در متغیر محیطی «HTTP_COOKIE» ذخیره می‌شوند و به شکل زیر هستند.

key1 = value1; key2 = value2; key3 = value3....

مثال زیر نحوه بازیابی کوکی‌ها را نشان می‌دهد..

#include <iostream>
#include <vector>  
#include <string>  
#include <stdio.h>  
#include <stdlib.h> 

#include <cgicc/CgiDefs.h> 
#include <cgicc/Cgicc.h> 
#include <cgicc/HTTPHTMLHeader.h> 
#include <cgicc/HTMLClasses.h>

using namespace std;
using namespace cgicc;

int main () {
   Cgicc cgi;
   const_cookie_iterator cci;

   cout << "Content-type:text/html\r\n\r\n";
   cout << "<html>\n";
   cout << "<head>\n";
   cout << "<title>Cookies in CGI</title>\n";
   cout << "</head>\n";
   cout << "<body>\n";
   cout << "<table border = \"0\" cellspacing = \"2\">";
   
   // get environment variables
   const CgiEnvironment& env = cgi.getEnvironment();

   for( cci = env.getCookieList().begin();
   cci != env.getCookieList().end(); 
   ++cci ) {
      cout << "<tr><td>" << cci->getName() << "</td><td>";
      cout << cci->getValue();                                 
      cout << "</td></tr>\n";
   }
   
   cout << "</table><\n";
   cout << "<br/>\n";
   cout << "</body>\n";
   cout << "</html>\n";
   
   return 0;
}

حال کد بالا را کامپایل کرده تا فایل «getcookies.cgi» تولید شود، با لینک زیر همه کوکی‌ها را بازیابی کنید.

/cgi-bin/getcookies.cgi

این لینک چهار کوکی که در بخش قبل تنظیم کرده بودیم را به همراه همه کوکی‌های موجود در کامپیوترتان لیست می‌کند.

UserID XYZ 
Password XYZ123 
Domain www.tutorialspoint.com 
Path /perl 

مثالی از آپلود فایل

برای اپلود یک فایل، باید خاصیت encrypte فرم HTML به صورت «multipart/form-data» تنظیم شده باشد. برچسب input به همراه خاصیت type نوع file، یک دکمه Browse تولید می‌کند.

<html>
   <body>
      <form enctype = "multipart/form-data" action = "/cgi-bin/cpp_uploadfile.cgi"
         method = "post">
         <p>File: <input type = "file" name = "userfile" /></p>
         <p><input type = "submit" value = "Upload" /></p>
      </form>
   </body>
</html>

خروجی کد فوق به شکل زیر خواهد بود.

برنامه‌نویسی وب در ++C

اسکریپت «cpp_uploadfile.cpp» برای مدیریت آپلود فایل، در زیر آمده است.

#include <iostream>
#include <vector>  
#include <string>  
#include <stdio.h>  
#include <stdlib.h> 

#include <cgicc/CgiDefs.h> 
#include <cgicc/Cgicc.h> 
#include <cgicc/HTTPHTMLHeader.h> 
#include <cgicc/HTMLClasses.h>

using namespace std;
using namespace cgicc;

int main () {
   Cgicc cgi;

   cout << "Content-type:text/html\r\n\r\n";
   cout << "<html>\n";
   cout << "<head>\n";
   cout << "<title>File Upload in CGI</title>\n";
   cout << "</head>\n";
   cout << "<body>\n";

   // get list of files to be uploaded
   const_file_iterator file = cgi.getFile("userfile");
   if(file != cgi.getFiles().end()) {
      // send data type at cout.
      cout << HTTPContentHeader(file->getDataType());
      // write content at cout.
      file->writeToStream(cout);
   }
   cout << "<File uploaded successfully>\n";
   cout << "</body>\n";
   cout << "</html>\n";
   
   return 0;
}

مثال بالا برای نوشتن محتوا در استریم cout طراحی شده اما می‌توان یک استریم فایل باز کرده و محتویات فایل آپلود شده را در فایلی در مکان دلخواه ذخیره کرد.

امیدواریم که از این آموزش لذت برده باشید، لطفاً نظرات خود را برای ما ارسال کنید.

منبع: ترجمه از سایت tutorialspoint.com

منبع عکس شاخص: Dev.to

اگر این نوشته‌ برایتان مفید بود لطفا کامنت بنویسید.

مطالعه دیگر جلسات این آموزش<< جلسه قبلی                    جلسه بعدی >>
مطلب پیشنهادی:  کامنت گذاری در ++C

دیدگاهتان را بنویسید

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

یک دیدگاه

  1. وب سایت تون اینقدر خوبه ک نمیدونم از کجا شروع کنم به خوندن
    من دیوانه وار c , c++ رو دوست دارم