Programmation Perl CGI
Qu'est-ce que CGI
CGI est actuellement maintenu par NCSA. NCSA définit CGI comme suit :
CGI (Common Gateway Interface), interface de passerelle commune, c'est un programme, s'exécute sur le serveur tel que : Serveur HTTP, fournissant une interface avec la page HTML du client.
Navigation Web
Afin de mieux comprendre le fonctionnement de CGI, nous pouvons commencer par le processus consistant à cliquer sur un lien ou une URL sur une page Web :
1. Utilisez votre navigateur pour accéder à l'URL et vous connecter au serveur Web HTTP.
2. Après avoir reçu les informations de la demande, le serveur Web analysera l'URL et vérifiera si le fichier consulté existe sur le serveur. Si le fichier existe, renverra le contenu du fichier, sinon un message d'erreur sera renvoyé.
3. Le navigateur reçoit des informations du serveur et affiche le fichier ou le message d'erreur reçu.
Le programme CGI peut être un script Python, un script PERL, un script SHELL, un programme C ou C++, etc.
Schéma d'architecture CGI
Prise en charge et configuration du serveur Web
Avant de faire de la programmation CGI, assurez-vous de Le serveur Web prend en charge CGI et dispose de gestionnaires CGI configurés.
Apache prend en charge la configuration CGI :
Configurez le répertoire CGI :
ScriptAlias /cgi-bin/ /var/www/cgi-bin/
Tous les programmes CGI d'exécution du serveur HTTP sont enregistrés dans un répertoire préconfiguré. Ce répertoire est appelé répertoire CGI, et par convention, il est nommé /var/www/cgi-bin.
Les fichiers CGI ont une extension .cgi, et Perl peut également utiliser une extension .pl.
Par défaut, le répertoire cgi-bin dans lequel le serveur Linux est configuré pour s'exécuter est /var/www.
Si vous souhaitez spécifier d'autres répertoires pour exécuter les scripts CGI, vous pouvez modifier le fichier de configuration httpd.conf comme suit :
<Directory "/var/www/cgi-bin"> AllowOverride None Options +ExecCGI Order allow,deny Allow from all </Directory>
Ajoutez le suffixe .pl dans AddHandler pour que nous puissions y accéder .Fichier de script Perl se terminant par pl :
AddHandler cgi-script .cgi .pl .py
Le premier programme CGI
Ci-dessous nous créons un fichier test.cgi, le code est le suivant :
#!/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;
Puis via le navigateur Ouvrez http://localhost/cgi-bin/test.cgi et le résultat est le suivant :
Le contenu de sortie de la première ligne du script est "Contenu -type: text/htmlrnrn" Envoyé au navigateur et indique au navigateur que le type de contenu à afficher est "text/html".
En-tête HTTP
Le "Content-type: text/html" dans le contenu du fichier test.cgi fait partie de l'en-tête HTTP, qui sera envoyé au navigateur pour l'indiquer le navigateur Le type de contenu du fichier du serveur.
Le format de l'en-tête HTTP est le suivant :
HTTP 字段名: 字段内容
Par exemple :
Content-type:text/html\r\n\r\n
Le tableau suivant présente les informations couramment utilisées dans les en-têtes HTTP des programmes CGI :
头 | 描述 |
---|---|
Content-type: | 请求的与实体对应的MIME信息。例如: Content-type:text/html |
Expires: Date | 响应过期的日期和时间 |
Location: URL | 用来重定向接收方到非请求URL的位置来完成请求或标识新的资源 |
Last-modified: Date | 请求资源的最后修改时间 |
Content-length: N | 请求的内容长度 |
Set-Cookie: String | 设置Http Cookie |
Variables d'environnement CGI
Tous les programmes CGI reçoivent les variables d'environnement suivantes, qui jouent un rôle important dans les programmes 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) |
Ce qui suit est un simple script CGI qui génère des variables d'environnement 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;
Téléchargement de fichiers
Si nous voulons implémenter le téléchargement de fichiers via Perl CGI, nous devons définir différents Informations d'en-tête, comme indiqué ci-dessous :
#!/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"); }
Utilisez la méthode GET pour transmettre des données
La méthode GET envoie les informations utilisateur codées au serveur. Les informations sur les données sont incluses dans l'URL. de la page demandée, séparés par "?", comme indiqué ci-dessous :
http://www.test.com/cgi-bin/test.cgi?key1=value1&key2=value2Quelques autres notes sur les requêtes GET :
Les requêtes GET peuvent être mises en cache
-
Requêtes GET Conserver dans l'historique du navigateur
Les requêtes GET peuvent être mises en signet
Les requêtes GET ne doivent pas être utilisées lors du traitement de données sensibles
Les requêtes GET ont des limites de longueur
Les requêtes GET ne doivent être utilisées que pour récupérer des données
URL simple exemple : méthode GET
Ce qui suit est une URL simple, utilisant la méthode GET pour envoyer deux paramètres au programme test.cgi :
/cgi-bin/test.cgi?name=php中文网&url=http://www.php.cn
Ce qui suit est le code du fichier 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;
Affichez le navigateur, le résultat est le suivant :
Exemple de formulaire simple : méthode GET
Ce qui suit est un formulaire en utilisant la méthode GET via HTML Envoyez deux éléments de données au serveur. Le script du serveur soumis est également le fichier test.cgi Le code test.html est le suivant :
<!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>
Dans le navigateur, l'effet d'exécution. est la suivante :
Utilisez la méthode POST pour transférer des données
L'utilisation de la méthode POST pour transférer des données vers le serveur est plus sécurisée et fiable . Certaines informations sensibles telles que les mots de passe des utilisateurs doivent utiliser POST pour transférer des données.
Ce qui suit est également test.cgi, qui peut également traiter les données du formulaire POST soumises par le navigateur :
#!/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;
Ce qui suit est un formulaire via HTML qui utilise la méthode GET pour envoyer deux données à le serveur, soumettre Le script du serveur est également le fichier test.cgi, et le code test.html est le suivant :
<!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>
Dans le navigateur, l'effet d'exécution est le suivant :
Par CGI, le programme transmet les données de la case à cocher
la case à cocher est utilisée pour soumettre une ou plusieurs données d'option. Le code test.html est le suivant :
<!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>
Ce qui suit. est le code du fichier 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 "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;
Dans le navigateur, l'effet d'exécution est le suivant :
Transférer les données Radio via le programme CGI
La radio les envoie uniquement au serveur. Passez une donnée, le code test.html est le suivant :
<!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>
le code du script test.cgi est le suivant :
#!/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;
Dans le navigateur, l'effet d'exécution est le suivant :
Transférer les données Textarea via le programme CGI
Transferts Textarea plusieurs lignes de données au serveur, le code test.html est le suivant :
<!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>
le code du script test.cgi est le suivant :
#!/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;
Dans le navigateur, l'effet d'exécution est le suivant :
Transférer les données déroulantes via le programme CGI
Code de la liste déroulante HTML Comme suit :
<!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>
test Code de script .cgi comme suit :
#!/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;
Dans le navigateur, l'effet d'exécution est le suivant :
Utilisation des Cookies en CGI
Un gros inconvénient dans le protocole http Il ne juge tout simplement pas l'identité de l'utilisateur, ce qui constitue un grand inconvénient pour les programmeurs. L’émergence de la fonction cookie pallie cette lacune.
Le cookie consiste à écrire des données d'enregistrement sur le disque dur du client via le navigateur du client lorsque le client accède au script. , les informations sur les données seront récupérées la prochaine fois que le client accédera au script, afin d'atteindre la fonction de discrimination d'identité. Les cookies sont souvent utilisés dans la vérification de l'identité.
Syntaxe du cookie
Le cookie http est envoyé via l'en-tête http, qui est antérieur au transfert de fichier. La syntaxe de set-cookie dans l'en-tête est la suivante :
Set-cookie:name=name;expires=date;path=path;domain=domain;secure<🎜. >
name=name : Vous devez définir la valeur du cookie (le nom ne peut pas utiliser ";" et ","), comment many Utilisez ";" pour séparer les valeurs de nom, par exemple : name1=name1;name2=name2;name3=name3.
expires=date : Durée de validité des cookies, format : expires="Wdy,DD-Mon-YYYY HH:MM:SS"
path=path : Définissez le chemin pris en charge par les cookies. Si le chemin est un chemin, le cookie sera dedans. répertoire. Valable pour tous les fichiers et sous-répertoires, par exemple : path="/cgi-bin/". Si le chemin est un fichier, le cookie sera valide pour ce fichier, par exemple : path="/cgi-bin/cookie. cgi".
domain=domain : Nom de domaine valide pour les cookies, par exemple : domain="www.php.cn"
sécurisé : Si ce flag est donné, cela signifie que le cookie ne peut être délivré que via le serveur https du protocole SSL.
- La réception des cookies est obtenue en définissant la variable d'environnement HTTP_COOKIE. Les programmes CGI peuvent obtenir des informations sur les cookies en récupérant cette variable.
Paramètres des cookiesLe paramétrage des cookies est très simple et le cookie sera envoyé séparément dans l'en-tête http. L'exemple suivant définit l'ID utilisateur, le mot de passe et expire dans les cookies :
#!/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 内容Rechercher un cookieLa page de récupération des informations sur les cookies est très simple. Les informations sur les cookies sont stockées dans la variable d'environnement CGI HTTP_COOKIE et le format de stockage. est le suivant :
#!/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";Le résultat de sortie de l'exemple ci-dessus est :
User ID = XYZ Password = XYZ123
Module CGIPerl fournit de nombreux modules CGI intégrés, les deux suivants sont couramment utilisés :
- Module CGI
- Berkeley cgi-lib.pl