Tiedot päivitetty 271299 ja taas työn alla 250105

shtml ja CGI-scriptit

WWW -sivuja voidaan käyttää käynnistämään ohjelmia palvelimella. Näin sivuja voidaan käyttää myös tietojen keräämiseen asiakkailta. Käytän tässä tarvittavista apuohjelmista nimeä script. Ohjelman voi kirjoittaa melkeimpä millä tahansa käytettävissä olevalla ohjelmointikielellä. Yleisimmin kuitenkin käytetään PERL :ä, joka on erityisen sopiva merkkisyötteen käsittelyyn.

Tämä sivu sisltää lähinnä yleisen pikaohjeen kaavakkeiden käyttöön.
Jos haluat perehtyä perusteellisemmin HTML -kaavakkeiden käyttöön, suosittelen linkkejä:
www.w3.org ja W3 schools .

Esimerkki

Esimerkissä käytetään html-sivua testi.html sekä Perlillä kirjoitettua scriptiä test.cgi , joka sijaitsee hakemistossa /home/httpd/cgi_bin ja jonka ajo-oikeudet ovat '605'. Tiedoston omistaa luuseri:users. Luuseri on serverissä kirjoilla oleva käyttäjä. Scriptin pitää sijaita määrätyssä hakemistossa. Esim Linuxissa käytetään yleensä hakemistoa /home/httpd/cgi-bin . Tämä polkumäärittely pitää tarkastaa WEB-palvelimen asetustiedostosta. Apachelle /etc/apache/httpd.conf :ssa ScriptAlias /cgi-bin/ "/home/httpd/cgi-bin/"

Tiedoston ensimmäisellä rivillä kerrotaan käyttöjärjestelmälle käytettävä komentotulkki. '#' saa rivin näyttämään kommentilta


TESTI.HTML

< html >  < head >  < title > PTM testpage < /title >  < /head > 
< img SRC="/icons/rainbow.gif"width=100% > 
< h1 > TESTPAGE < /h1 > 

< form ACTION="/cgi-bin/test.cgi" METHOD="POST" > 
< input NAME="ekarivi" TYPE=TEXT maxlength=29 SIZE=30 > 
< br > 
< select name="menunimi" valinnainen > 
< option selected >  iso
< option > keskikokoinen
< option > pieni
< /select > 
< br > 
< input type=radio name="group2" value="Water" >  Vesi& lt br > 
< input type=radio name="group2" value="Beer" >  Olut < br > 
< input type=radio name="group2" value="Wine" checked >  Viini < br > 

< input TYPE=SUBMIT VALUE="Lähetys" > 
< input type=RESET value="RESET" > 
< /form > 
< img SRC="/icons/rainbow.gif" width=100% > 
< /body >  < /html > 

TESTI.CGI

#!/usr/bin/perl
# 211204 PTM
print "Content-type: text/html\n\n";
print " < html > < HEAD > < TITLE > Machinelog < /TITLE > </HEAD > \n";
print" < BODY BACKGROUND=\x22/icons/marble.gif\x22 > \n";
print" < IMG SRC=\x22/icons/rainbow.gif\x22 HEIGHT=14 WIDTH=90% > <br > \n";
#-------------------------------------
$addr=$ENV{'REMOTE_ADDR'}; 
print " < br > Your address = $addr < br > \n";
read(STDIN,$kaavake,$ENV{'CONTENT_LENGTH'});
$kaavake =~ s/\+/ /g;
print "$kaavake < br > \n";
print" < IMG SRC=\x22/icons/rainbow.gif\x22 HEIGHT=14 WIDTH=90% > < br > \n";
print " < /body > < /html > \n";

Ylläolevassa esimerkissä
- FORM ACTION="/cgi-bin/test.cgi" kutsuttava ohjelma.
- METHOD="POST" tapa, jolla kaavakkeen tieto tarjotaan kutsuttavalle ohjelmalle. Tämä ei tarkoita sähköpostia. Toinen metodi, "GET" ei toimi tässä esimerkissä.

- INPUT TYPE=TEXT tekstirivin syöttö. Lisäyksellä 'maxlength=29 SIZE=30' rajataan syötteen pituudeksi 29 merkkiä. TEXT-syötteessä ei voi olla rivinvaihtoja.
- INPUT TYPE=radio valintapainike - input TYPE=SUBMIT lähetyspainike.
- input TYPE=RESET lähetyspainike.
- VALUE="Painike" painikkeen oletusarvo, joka on myös painikkeen tekstinä.
Esimerkin mukainen FORM näkyy WEB-sivulla alla olevan mallin mukaisena
Mallin mukaisesta esimerkkitapauksesta saadaan merkkijono:
ekarivi=Hello&menunimi=iso&group2=Wine
Välimerkeillä '=' ja '&' erotetaan avaimet ja syötteet toisistaan:
'ekarivi=Hello' sisältää avaimen 'ekarivi' ja syötteen 'Hello' . Seuraava avain=syöte on 'menunimi=iso' .
Välilyönnit olisi korvattu '+' -merkillä. Muita white-space -merkkejä (esim tab) ei syötteesen edes pysty kirjoittamaan.


Asiakkaan kirjoittama tieto siirtyy merkkijonona sitä käsittelevälle scriptille ympäristömuuttujana. Merkkijono sisältää asiakkaan syötteen lisäksi erilaisia ohjausmerkkejä. Lisäksi esim scandit ja erikoismerkit on korvattu heksadesimaaliluvuilla. Esimerkiksi syötteestä åäöÅÄÖ!"#¤%&/()=? syntyy merkkijono %E5%E4%F6%C5%C4%D6%21%22%23%A4%25%26%2F%28%29%3D%3F .


Alla oleva CGI-SCRIPT tallettaa taulukkosi keräämän datan suoraan EXCEL:llä käsiteltävään muotoon ilman että sinun tarvitsee muuttaa kuin talletustiedoston nimi. Koodissa saattaa olla virheitä ja typeryyksiä, joten suosittelen, että tutkit sen tarkkaan.
CGI-scriptiö voi testata myös kutsumalla sitä komentoriviltä, siis ei web-sivun kautta. Tällöin PERL-kääntäjä ilmoittaa ruudulla syntaksivirheistä paljon selkeämmin, kuin webbiserverin ja selaimen läpi.
Näin testatessa ei tietenkään näe, toimiiko merkkijonon käsittely halutulla tavalla, ellei järjestä ohjelmalle syötettä muulla tavoin.

YLEIS.CGI

#!/usr/bin/perl
#270105 ptmusta @ utu.fi
#----------------------------------------------------------
#Ohjelma ottaa vastaan minkä tahansa taulukon, irrottaa siitä
#avain - arvo -parit ja tallettaa ne tiedostoksi, jossa
#ensimmäisellä rivillä on otsikkona lueteltu avaimet ja sitä seuraavilla
#arvot pilkuilla erotettuina ja lainausmerkeillä petattuina.
#Sarakkeiden lukumäärä eli kaavakkeen syötepisteiden määrä on
#rajoittamaton.
#Tässä muodossa data siirtyy suoraan comma delimited -muodossa esim EXCEL:llä
#käsiteltäväksi.
#Comma delimited:n hyväksyvät useimmat taulukkolaskenta- ja
#kortistoohjelmat

#Kaksoissyöttöä ei tarkisteta, joten asiakas pystyy syöttämään saman
#datan moneen kertaan
#Myös virhetarkastelu puuttuu kokonaan.
#----------------------------------------------
#Tiedosto, johon data talletetaan:
$file="DATA.LOG";

#Luetaan WWW-serverin lähettämä kaavake
read(STDIN,$kaavake,$ENV{'CONTENT_LENGTH'});

#Tämä tarvitaan jotta WWW-serveri osaa tulostaa
#CGI:ltä saamansa materiaalin:
## print "Content-type: text/shtml\n\n"

print '<html><body>';
#Tämä kuuluu mukaan vaikkei olekaan täysin välttämätön :)
print "Kiitos tiedoista<br>";
#----------------------------------------------
#KÄSITTELYJÄRJESTYS ON TÄRKEÄ !
#serveriltä tulevassa kaavakkeessa =&+ ovat koodattuna hexaksi,
#joten hex-alpha-koodaus tehdään viimeisenä, kun nämä merkit on jo
#käsitelty !

#Palautetaan '+':t välilyönneiksi:
$kaavake =~ s/\+/ /g;

#irroitetaan alkiot eli avain=syote -parit toisistaan. (Tehdään vektori)
@alkio = split(/&/,$kaavake);

#Käsitellään kaikki @alkio-taulukon avain-arvo -parit
foreach $pari(@alkio){

#Jaetaan nimi avaimeksi ja arvoksi:
($avain,$arvo) = split(/=/,$pari,2);

#Muutetaan %xx heksoista alphoiksi:
$avain =~ s/%(..)/pack("c",hex($1))/ge;
$arvo =~ s/%(..)/pack("c",hex($1))/ge;

#Tulostetaan shtml-sivulle asiakkaan iloksi:
print "$avain = $arvo <br>";

#Luodaan merkkijonot, jossa on pilkut ja lainausmerkit mukana:
$avaimet = $avaimet . $komma . '"' . $avain . '"';
$arvot = $arvot . $komma . '"' . $arvo . '"';

#Estetään pilkun tuleminen jonon ensimmäiseksi tai viimeiseksi
#merkiksi antamalla kommalle arvo vasta 1. kierroksen jälkeen:
$komma = ',';
};

print"< /body> < /html>"
#-------------Se siitä shtml-sivusta----------------------------
#Kirjoitetaan käsitelty kaavake tiedostoon

open (LOKIFILE, ">>$file");

@status=stat(LOKIFILE);
#Tämä osa huolehtii siitä, että tiedoston alkuun tulee avaimien nimet vain, jos tiedosto on tyhjä: if($status[7] == 0){
print LOKIFILE "$avaimet\n";};

# Talletetaan varsinaiset datat:
print LOKIFILE "$arvot\n";

close (LOKIFILE);
#------------------This is the end !-----------------------

PTMUSTA at UTU.FI