Pengaturcaraan CGI Perl
Apakah itu CGI
CGI kini diselenggara oleh NCSA mentakrifkan CGI seperti berikut:
CGI (Antara Muka Gerbang Biasa), antara muka gerbang biasa, ia adalah. program , berjalan pada pelayan seperti: pelayan HTTP, menyediakan antara muka dengan halaman HTML klien.
Semakan imbas web
Untuk lebih memahami cara CGI berfungsi, kita boleh mulakan dengan proses mengklik pautan atau URL pada halaman web:
1 Gunakan penyemak imbas anda untuk mengakses URL dan menyambung ke pelayan web HTTP.
2. Selepas menerima maklumat permintaan, pelayan web akan menghuraikan URL dan menyemak sama ada fail yang diakses wujud pada pelayan Jika fail itu wujud, kembalikan kandungan fail tersebut. jika tidak mesej ralat akan dikembalikan.
3. Penyemak imbas menerima maklumat daripada pelayan dan memaparkan fail atau mesej ralat yang diterima.
Atur cara CGI boleh menjadi skrip Python, skrip PERL, skrip SHELL, program C atau C++, dsb.
Rajah seni bina CGI
Sokongan dan konfigurasi pelayan web
Sebelum anda melakukan pengaturcaraan CGI, pastikan anda Pelayan web menyokong CGI dan mempunyai pengendali CGI dikonfigurasikan.
Apache menyokong konfigurasi CGI:
Sediakan direktori CGI:
ScriptAlias /cgi-bin/ /var/www/cgi-bin/
Semua program CGI pelaksanaan pelayan HTTP disimpan dalam direktori pra-konfigurasi. Direktori ini dipanggil direktori CGI, dan mengikut konvensyen, ia dinamakan /var/www/cgi-bin.
Fail CGI mempunyai sambungan .cgi dan Perl juga boleh menggunakan sambungan .pl.
Secara lalai, direktori cgi-bin tempat pelayan Linux dikonfigurasikan untuk dijalankan ialah /var/www.
Jika anda ingin menentukan direktori lain untuk menjalankan skrip CGI, anda boleh mengubah suai fail konfigurasi httpd.conf seperti berikut:
<Directory "/var/www/cgi-bin"> AllowOverride None Options +ExecCGI Order allow,deny Allow from all </Directory>
Tambah akhiran .pl dalam AddHandler supaya kami boleh mengaksesnya . Fail skrip Perl yang berakhir dengan pl:
AddHandler cgi-script .cgi .pl .py
Program CGI pertama
Di bawah kami mencipta fail test.cgi, kodnya adalah seperti berikut:
#!/usr/bin/perl print "Content-type:text/html\r\n\r\n"; print '<html>'; print '<head>'; print '<meta charset="utf-8">'; print '<title>php中文网(php.cn)</title>'; print '</head>'; print '<body>'; print '<h2>Hello Word! </h2>'; print '<p>来自php中文网第一个 CGI 程序。</p>'; print '</body>'; print '</html>'; 1;
Kemudian melalui pelayar Buka http://localhost/cgi-bin/test.cgi dan output adalah seperti berikut:
Kandungan output baris pertama skrip ialah "Kandungan -type: text/htmlrnrn" Dihantar ke penyemak imbas dan memberitahu penyemak imbas bahawa jenis kandungan yang akan dipaparkan ialah "teks/html".
Pengepala HTTP
"Content-type: text/html" dalam kandungan fail test.cgi ialah sebahagian daripada pengepala HTTP, yang akan dihantar kepada penyemak imbas untuk memberitahu pelayar Jenis kandungan fail pelayan.
Format pengepala HTTP adalah seperti berikut:
HTTP 字段名: 字段内容
Contohnya:
Content-type:text/html\r\n\r\n
Jadual berikut memperkenalkan maklumat yang biasa digunakan dalam pengepala HTTP dalam program CGI:
头 | 描述 |
---|---|
Content-type: | 请求的与实体对应的MIME信息。例如: Content-type:text/html |
Expires: Date | 响应过期的日期和时间 |
Location: URL | 用来重定向接收方到非请求URL的位置来完成请求或标识新的资源 |
Last-modified: Date | 请求资源的最后修改时间 |
Content-length: N | 请求的内容长度 |
Set-Cookie: String | 设置Http Cookie |
Pembolehubah persekitaran CGI
Semua program CGI menerima pembolehubah persekitaran berikut, yang memainkan peranan penting dalam program CGI:
变量名 | 描述 |
---|---|
CONTENT_TYPE | 这个环境变量的值指示所传递来的信息的MIME类型。目前,环境变量CONTENT_TYPE一般都是:application/x-www-form-urlencoded,他表示数据来自于HTML表单。 |
CONTENT_LENGTH | 如果服务器与CGI程序信息的传递方式是POST,这个环境变量即使从标准输入STDIN中可以读到的有效数据的字节数。这个环境变量在读取所输入的数据时必须使用。 |
HTTP_COOKIE | 客户机内的 COOKIE 内容。 |
HTTP_USER_AGENT | 提供包含了版本数或其他专有数据的客户浏览器信息。 |
PATH_INFO | 这个环境变量的值表示紧接在CGI程序名之后的其他路径信息。它常常作为CGI程序的参数出现。 |
QUERY_STRING | 如果服务器与CGI程序信息的传递方式是GET,这个环境变量的值即使所传递的信息。这个信息经跟在CGI程序名的后面,两者中间用一个问号'?'分隔。 |
REMOTE_ADDR | 这个环境变量的值是发送请求的客户机的IP地址,例如上面的192.168.1.67。这个值总是存在的。而且它是Web客户机需要提供给Web服务器的唯一标识,可以在CGI程序中用它来区分不同的Web客户机。 |
REMOTE_HOST | 这个环境变量的值包含发送CGI请求的客户机的主机名。如果不支持你想查询,则无需定义此环境变量。 |
REQUEST_METHOD | 提供脚本被调用的方法。对于使用 HTTP/1.0 协议的脚本,仅 GET 和 POST 有意义。 |
SCRIPT_FILENAME | CGI脚本的完整路径 |
SCRIPT_NAME | CGI脚本的的名称 |
SERVER_NAME | 这是你的 WEB 服务器的主机名、别名或IP地址。 |
SERVER_SOFTWARE | 这个环境变量的值包含了调用CGI程序的HTTP服务器的名称和版本号。例如,上面的值为Apache/2.2.14(Unix) |
Berikut ialah skrip CGI mudah yang mengeluarkan pembolehubah persekitaran CGI:
#!/usr/bin/perl print "Content-type: text/html\n\n"; print '<meta charset="utf-8">'; print "<font size=+1>环境变量:</font>\n"; foreach (sort keys %ENV) { print "<b>$_</b>: $ENV{$_}<br>\n"; } 1;
Muat turun fail
Jika kita ingin melaksanakan muat turun fail melalui Perl CGI, kita perlu menetapkan berbeza maklumat pengepala, seperti yang ditunjukkan di bawah:
#!/usr/bin/perl # HTTP Header print "Content-Type:application/octet-stream; name=\"FileName\"\r\n"; print "Content-Disposition: attachment; filename=\"FileName\"\r\n\n"; # Actual File Content will go hear. open( FILE, "<FileName" ); while(read(FILE, $buffer, 100) ) { print("$buffer"); }
Gunakan kaedah GET untuk menghantar data
Kaedah GET menghantar maklumat pengguna yang dikodkan ke pelayan Maklumat data disertakan dalam URL daripada halaman yang diminta, untuk dipisahkan dengan "?", seperti yang ditunjukkan di bawah:
http://www.test.com/cgi-bin/test.cgi?key1=value1&key2=value2Beberapa nota lain tentang permintaan GET:
Permintaan GET boleh dicache
-
DAPAT permintaan Simpan dalam sejarah penyemak imbas
Dapatkan permintaan boleh ditandakan
Permintaan GET tidak boleh digunakan semasa mengendalikan data sensitif
Permintaan GET mempunyai had panjang
Permintaan GET hanya boleh digunakan untuk mendapatkan data
URL ringkas contoh: Kaedah GET
Berikut ialah URL ringkas, menggunakan kaedah GET untuk menghantar dua parameter ke program test.cgi:
/cgi-bin/test.cgi?name=php中文网&url=http://www.php.cn
Berikut ialah kod fail test.cgi :
#!/usr/bin/perl local ($buffer, @pairs, $pair, $name, $value, %FORM); # 读取文本信息 $ENV{'REQUEST_METHOD'} =~ tr/a-z/A-Z/; if ($ENV{'REQUEST_METHOD'} eq "GET") { $buffer = $ENV{'QUERY_STRING'}; } # 读取 name/value 对信息 @pairs = split(/&/, $buffer); foreach $pair (@pairs) { ($name, $value) = split(/=/, $pair); $value =~ tr/+/ /; $value =~ s/%(..)/pack("C", hex())/eg; $FORM{$name} = $value; } $name = $FORM{name}; $url = $FORM{url}; print "Content-type:text/html\r\n\r\n"; print "<html>"; print "<head>"; print '<meta charset="utf-8">'; print '<title>php中文网(php.cn)</title>'; print "</head>"; print "<body>"; print "<h2>$name网址:$url</h2>"; print "</body>"; print "</html>"; 1;
Lihat penyemak imbas, output adalah seperti berikut:
Contoh borang mudah: Kaedah GET
Berikut ialah borang menggunakan kaedah GET melalui HTML Hantar dua keping data ke pelayan Skrip pelayan yang diserahkan juga ialah fail test.cgi Kod test.html adalah seperti berikut:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>php中文网(php.cn)</title> </head> <body> <form action="/cgi-bin/test.cgi" method="get"> 站点名称: <input type="text" name="name"> <br /> 站点 URL: <input type="text" name="url" /> <input type="submit" value="提交" /> </form> </body> </html>
Dalam pelayar, kesan pelaksanaan. adalah seperti berikut:
Gunakan kaedah POST untuk memindahkan data
Menggunakan kaedah POST untuk memindahkan data ke pelayan adalah lebih selamat dan boleh dipercayai . Beberapa maklumat sensitif seperti kata laluan pengguna perlu menggunakan POST untuk memindahkan data.
Berikut juga test.cgi, yang juga boleh memproses data borang POST yang diserahkan oleh penyemak imbas:
#!/usr/bin/perl local ($buffer, @pairs, $pair, $name, $value, %FORM); # 读取文本信息 $ENV{'REQUEST_METHOD'} =~ tr/a-z/A-Z/; if ($ENV{'REQUEST_METHOD'} eq "POST") { read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'}); }else { $buffer = $ENV{'QUERY_STRING'}; } # 读取 name/value 对信息 @pairs = split(/&/, $buffer); foreach $pair (@pairs) { ($name, $value) = split(/=/, $pair); $value =~ tr/+/ /; $value =~ s/%(..)/pack("C", hex())/eg; $FORM{$name} = $value; } $name = $FORM{name}; $url = $FORM{url}; print "Content-type:text/html\r\n\r\n"; print "<html>"; print "<head>"; print '<meta charset="utf-8">'; print '<title>php中文网(php.cn)</title>'; print "</head>"; print "<body>"; print "<h2>$name网址:$url</h2>"; print "</body>"; print "</html>"; 1;
Berikut ialah borang melalui HTML yang menggunakan kaedah GET untuk menghantar dua data ke pelayan, serahkan Skrip pelayan juga merupakan fail test.cgi, dan kod test.html adalah seperti berikut:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>php中文网(php.cn)</title> </head> <body> <form action="/cgi-bin/test.cgi" method="post"> 站点名称: <input type="text" name="name"> <br /> 站点 URL: <input type="text" name="url" /> <input type="submit" value="提交" /> </form> </body> </html>
Dalam penyemak imbas, kesan pelaksanaan adalah seperti berikut:
Melalui CGI Program meluluskan data kotak semak
kotak semak digunakan untuk mengemukakan satu atau lebih data pilihan. ialah kod fail test.cgi:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>php中文网(php.cn)</title> </head> <body> <form action="/cgi-bin/test.cgi" method="POST" target="_blank"> <input type="checkbox" name="php" value="on" /> php中文网 <input type="checkbox" name="google" value="on" /> Google <input type="submit" value="选择站点" /> </form> </body> </html>
Dalam penyemak imbas, kesan pelaksanaan adalah seperti berikut:
Pindahkan data Radio melalui program CGI
Radio hanya menghantar data ke pelayan Lulus data, kod test.html adalah seperti berikut:
#!/usr/bin/perl local ($buffer, @pairs, $pair, $name, $value, %FORM); # 读取信息 $ENV{'REQUEST_METHOD'} =~ tr/a-z/A-Z/; if ($ENV{'REQUEST_METHOD'} eq "POST") { read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'}); }else { $buffer = $ENV{'QUERY_STRING'}; } # 读取 name/value 对信息 @pairs = split(/&/, $buffer); foreach $pair (@pairs) { ($name, $value) = split(/=/, $pair); $value =~ tr/+/ /; $value =~ s/%(..)/pack("C", hex())/eg; $FORM{$name} = $value; } if( $FORM{php} ){ $php_flag ="ON"; }else{ $php_flag ="OFF"; } if( $FORM{google} ){ $google_flag ="ON"; }else{ $google_flag ="OFF"; } print "Content-type:text/html\r\n\r\n"; print "<html>"; print "<head>"; print '<meta charset="utf-8">'; print '<title>php中文网(php.cn)</title>'; print "</head>"; print "<body>"; print "<h2> php中文网选中状态 : $php_flag</h2>"; print "<h2> Google 选择状态 : $google_flag</h2>"; print "</body>"; print "</html>"; 1;
kod skrip test.cgi adalah seperti berikut:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>php中文网(php.cn)</title> </head> <body> <form action="/cgi-bin/test.cgi" method="post" target="_blank"> <input type="radio" name="site" value="php" /> php中文网 <input type="radio" name="site" value="google" /> Google <input type="submit" value="提交" /> </form> </body> </html>
Dalam penyemak imbas, kesan pelaksanaan adalah seperti berikut:
Pindahkan data Textarea melalui program CGIPemindahan Textarea berbilang baris data ke pelayan, kod test.html adalah seperti berikut:
#!/usr/bin/perl local ($buffer, @pairs, $pair, $name, $value, %FORM); # 读取信息 $ENV{'REQUEST_METHOD'} =~ tr/a-z/A-Z/; if ($ENV{'REQUEST_METHOD'} eq "POST") { read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'}); }else { $buffer = $ENV{'QUERY_STRING'}; } # 读取 name/value 对信息 @pairs = split(/&/, $buffer); foreach $pair (@pairs) { ($name, $value) = split(/=/, $pair); $value =~ tr/+/ /; $value =~ s/%(..)/pack("C", hex())/eg; $FORM{$name} = $value; } $site = $FORM{site}; print "Content-type:text/html\r\n\r\n"; print "<html>"; print "<head>"; print '<meta charset="utf-8">'; print '<title>php中文网(php.cn)</title>'; print "</head>"; print "<body>"; print "<h2> 选择的网站 $site</h2>"; print "</body>"; print "</html>"; 1;
kod skrip test.cgi adalah seperti berikut:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>php中文网(php.cn)</title> </head> <body> <form action="/cgi-bin/test.cgi" method="post" target="_blank"> <textarea name="textcontent" cols="40" rows="4"> 在这里输入内容... </textarea> <input type="submit" value="提交" /> </form> </body> </html>
Dalam penyemak imbas, kesan pelaksanaan adalah seperti berikut :
Pindahkan data lungsur turun melalui program CGIKod kotak lungsur HTML Seperti berikut:
#!/usr/bin/perl local ($buffer, @pairs, $pair, $name, $value, %FORM); # 读取信息 $ENV{'REQUEST_METHOD'} =~ tr/a-z/A-Z/; if ($ENV{'REQUEST_METHOD'} eq "POST") { read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'}); }else { $buffer = $ENV{'QUERY_STRING'}; } # 读取 name/value 对信息 @pairs = split(/&/, $buffer); foreach $pair (@pairs) { ($name, $value) = split(/=/, $pair); $value =~ tr/+/ /; $value =~ s/%(..)/pack("C", hex())/eg; $FORM{$name} = $value; } $text_content = $FORM{textcontent}; print "Content-type:text/html\r\n\r\n"; print "<html>"; print "<head>"; print '<meta charset="utf-8">'; print '<title>php中文网(php.cn)</title>'; print "</head>"; print "<body>"; print "<h2>输入的文本内容为:$text_content</h2>"; print "</body>"; print "</html>"; 1;
ujian Kod skrip .cgi seperti berikut:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>php中文网(php.cn)</title> </head> <body> <form action="/cgi-bin/test.cgi" method="post" target="_blank"> <select name="dropdown"> <option value="php" selected>php中文网</option> <option value="google">Google</option> </select> <input type="submit" value="提交"/> </form> </body> </html>
Dalam penyemak imbas, kesan pelaksanaan adalah seperti berikut:
Menggunakan Kuki dalam CGI
Kelemahan besar dalam protokol http Ia hanya tidak menilai identiti pengguna, yang membawa kesulitan besar kepada pengaturcara. Kemunculan fungsi kuki menggantikan kekurangan ini.
Kuki adalah untuk menulis data rekod pada pemacu keras pelanggan melalui penyemak imbas pelanggan apabila pelanggan mengakses skrip. , maklumat data akan diambil pada kali seterusnya pelanggan mengakses skrip, untuk mencapai fungsi diskriminasi identiti Kuki sering digunakan dalam pengesahan identiti.
Sintaks kuki
Kuki http dihantar melalui pengepala http, yang lebih awal daripada pemindahan fail Sintaks set-cookie dalam pengepala adalah seperti berikut:
#!/usr/bin/perl local ($buffer, @pairs, $pair, $name, $value, %FORM); # 读取信息 $ENV{'REQUEST_METHOD'} =~ tr/a-z/A-Z/; if ($ENV{'REQUEST_METHOD'} eq "POST") { read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'}); }else { $buffer = $ENV{'QUERY_STRING'}; } # 读取 name/value 对信息 @pairs = split(/&/, $buffer); foreach $pair (@pairs) { ($name, $value) = split(/=/, $pair); $value =~ tr/+/ /; $value =~ s/%(..)/pack("C", hex())/eg; $FORM{$name} = $value; } $site = $FORM{dropdown}; print "Content-type:text/html\r\n\r\n"; print "<html>"; print "<head>"; print '<meta charset="utf-8">'; print '<title>php中文网(php.cn)</title>'; print "</head>"; print "<body>"; print "<h2>选择的网站是:$site</h2>"; print "</body>"; print "</html>"; 1;<🎜. >
name=name: Anda perlu menetapkan nilai kuki (nama tidak boleh menggunakan ";" dan ","), bagaimana banyak Gunakan ";" untuk memisahkan nilai nama, contohnya: name1=name1;name2=name2;name3=name3.
tamat=tarikh: Tempoh sah kuki, format: luput="Wdy,DD-Mon-YYYY HH:MM:SS"
path=path: Tetapkan laluan yang disokong oleh kuki Jika laluan ialah laluan, kuki akan berada dalam ini direktori. Sah untuk semua fail dan subdirektori, contohnya: path="/cgi-bin/". cgi".
domain=domain: Nama domain yang sah untuk kuki, contohnya: domain="www.php.cn"
selamat: Jika bendera ini diberikan, ini bermakna kuki hanya boleh dihantar melalui pelayan https protokol SSL.
- Penerimaan kuki dicapai dengan menetapkan pembolehubah persekitaran Program CGI HTTP_COOKIE boleh mendapatkan maklumat kuki dengan mendapatkan semula pembolehubah ini.
Tetapan KukiTetapan kuki adalah sangat mudah dan kuki akan dihantar secara berasingan dalam pengepala http. Contoh berikut menetapkan ID Pengguna, Kata Laluan dan tamat tempoh dalam kuki:
Set-cookie:name=name;expires=date;path=path;domain=domain;secureCari KukiHalaman perolehan maklumat kuki adalah sangat mudah. Maklumat kuki disimpan dalam pembolehubah persekitaran CGI HTTP_COOKIE, dan format storan adalah seperti berikut:
#!/usr/bin/perl print "Set-Cookie:UserID=XYZ;\n"; print "Set-Cookie:Password=XYZ123;\n"; print "Set-Cookie:Expires=Tuesday, 31-Dec-2017 23:12:40 GMT";\n"; print "Set-Cookie:Domain=www.php.cn;\n"; print "Set-Cookie:Path=/perl;\n"; print "Content-type:text/html\r\n\r\n"; ...........其他 HTML 内容Hasil keluaran contoh di atas ialah:
#!/usr/bin/perl $rcvd_cookies = $ENV{'HTTP_COOKIE'}; @cookies = split /;/, $rcvd_cookies; foreach $cookie ( @cookies ){ ($key, $val) = split(/=/, $cookie); # splits on the first =. $key =~ s/^\s+//; $val =~ s/^\s+//; $key =~ s/\s+$//; $val =~ s/\s+$//; if( $key eq "UserID" ){ $user_id = $val; }elsif($key eq "Password"){ $password = $val; } } print "User ID = $user_id\n"; print "Password = $password\n";
modul CGIPerl menyediakan banyak modul CGI terbina dalam, dua berikut biasa digunakan:
- modul CGI
- Berkeley cgi-lib.pl