CGI-ohjelmointi, HTTP-protokolla

Jatketaan Pythonin, CGI-ohjelmoinnin ja HTTP-protokollan parissa.

Uusin Python ja CGI-ohjelmointiluento (youtube)

Vanha Python ja CGI-ohjelmointiluento (youtube)

Luentoesimerkit: jinja.cgi-esimerkki (Lähdekoodi, Jinja template)

Toinen jinja-esimerkki (Lähdekoodi, Pohjatemplate, Toinen template)

JSON, omat luokat, lomakkeen korvaaminen linkillä (Lähdekoodi, Template )

Lomake - form

form-elementti määrittelee lomakkeen varsinaisen alkamis- ja loppumiskohdan. form-elementin sisään sijoitetaan kaikki varsinaiset lomake-elementit (tekstikentät, valintaruudut, yms.), jotka tulevat näkyviin lomakkeelle. form-elementin attribuuteilla eli ominaisuuksilla voidaan määritellä tarkemmin lomakkeen käyttäytymistä. Seuraavassa lyhyt esimerkki form-elementin käytöstä:

<!DOCTYPE html>
<html>
<head>
<title>Esimerkkilomake</title>
</head>
<body>
<h1>Esimerkkilomake</h1>
<form action="http://palvelin/teepase.cgi" method="post">
.. lomake-elementit tulevat tänne..
</form>
</body>
</html>

action-attribuutti

action-attribuutti kertoo lomakkeelle osoitteen, jossa lomakkeen käsittelevä CGI-ohjelma sijaitsee. Seuraavassa muutama esimerkki action-attribuutin käytöstä. Ensimmäisessä esimerkissä on perinteinen absoluuttinen hakemistoviittaus ohjelmaan, joka käsittelee lomakkeelle syötetyn datan.

<form action="http://palvelin/teepase.cgi" method="post">

Edellisen esimerkin mukaisesti lähetettynä data tulee koodattuna application/x-www-form-urlencoded-muodossa.

<form action="http://palvelin/teepase.cgi" method="post" enctype="multipart/form-data">

Antamalla enctype-attribuutin arvoksi multipart/form-data voidaan lomakkeeseen lisätä myös tiedostoja

method-attribuutti

method-attribuutti kertoo kuinka lomakkeen sisältämä data toimitetaan datan käsittelevälle ohjelmalle. Attribuutin mahdolliset arvot ovat post ja get.

method-attribuutti arvolla get saa aikaan lomakkeella olevien tietojen siirtämisen URL:n yhteydessä. Seuraavassa on esitelty muoto, jossa tiedot siirretään lomakkeen käsittelevälle ohjelmalle. Lomakkeelta siirrettävät tiedot ovat nähtävillä selaimen osoitepalkissa (location, address)

http://palvelin/teepase.cgi?Nimi=Etunimi+Sukunimi&email=Sahk%F6postiosoite&kommentti=t%E4h%E4n+kommentti&laheta=L%E4het%E4+kommenttisi

URL:n mukana tulevien tietojen muoto näyttää ensi silmäyksellä sekavalle. Kuitenkin sieltä on helposti erotettavissa lomakkeen tiedot. Lomakkeen käsittelevän ohjelman osoite ja lomakkeen tiedot on erotettu kysymysmerkillä (?). Eri kenttien tiedot on erotettu &-merkillä. Lomakekentän nimi ja arvo on erotettu yhtä suuri kuin -merkillä (=). Lomakkeessa olevat skandit (ä,ö,å) ja erikoismerkit on koodattu heksadesimaaliluvuiksi ja välilyöntien paikalla on plus-merkki (+) tai %20.

Graphic1

GET-metodin käyttäminen soveltuu ainoastaan hyvin pienille lomakkeille, koska kaikki sen sisältämät tiedot siirretään URL:n mukana. GET-metodia käytetään silloin kun halutaan etsiä jotain tietoa eikä tehdä mitään muutoksia.

POST-metodia käytettäessä tiedot eivät siirry URL:n mukana, vaan vastaanottavan ohjelman on luettava ne STDIN-muuttujasta. POST-arvoa kannattaa käyttää erityisesti suuren tietomäärän siirtämiseksi lomakkeelta käsittelevälle ohjelmalle. Lomakkeelta siirtyvät tiedot eivät myöskään ole käyttäjän nähtävissä käytettäessä post-metodia. POST-metodia käytetään kun lomake aiheuttaa lisäyksiä, muutoksia tai poistoja

<!DOCTYPE html">
<html>
<head>
<title>Esimerkkilomake</title>
</head>
<body>
<h1>Esimerkkilomake</h1>
<form action="http://palvelin/teepase.cgi" method="post">
<p>
<label for="name">Nimi: </label>
<input id="name" type="text" name="Nimi" value="Etunimi Sukunimi" />
</p>
<p>
<label for="email">Email: </label>
<input id="email" type="text" name="email" value="Sahköpostiosoite" />
</p>
<p>
<label for="kommentti">Kommentti: </label>
<input id="kommentti" type="text" name="kommentti" value="tähän kommentti" />
</p>
<p>
<input type="submit" name="laheta" value="Lähetä kommenttisi" />
</p>
</form>
</body>
</html>

Lomake-elementit

WWW-lomakkeille voidaan lisätä hyvin monenlaisia elementtejä, joiden avulla lomakkeista saadaan käyttökelpoisia tehtäväänsä. Erilaisia elementtejä käyttämällä lomakkeesta voidaan saada monipuolinen ja pystytään jopa hieman rajoittamaan käyttäjän antamia syötteitä. Varsin usein lomakkeelle tehdään pelkästään erilaisia tekstikenttiä, mutta muitakin mahdollisuuksia kannattaa toki ajatella.

Seuraavassa listassa on lyhyesti esiteltynä erilaisia lomakekenttiä, joita lomakkeelle voidaan sijoittaa. Kuvauksen perässä on luvun numero, jossa elementtiä käsitellään tarkemmin.

Katso myös HTML5:n uudet input-elementin tyypit

Kentän otsikko - label

label-elementti toimii lomake-elementtien otsikkona.

<label>Nimi:
<input type="text" name="Nimi" value="Etunimi Sukunimi"
/></label>

for-attribuuttia käytetään yhdistämään otsikko varsinaiseen lomake-elementtiin jos lomake-elementtiä ei voida sijoittaa suoraan labelin sisään. Lomake-elementin id-attribuutin ja otsikon for-attribuutin arvojen on oltava samat. Arvojen on oltava yksikäsitteiset, joten otsikko voi viitata ainoastaan yhteen lomake-elementtiin. Seuraavassa esimerkki label-elementin käytöstä:

<label
for="name">Nimi:
</label><input id="name"
type="text" name="Nimi" value="Etunimi Sukunimi"
/>

accesskey-attribuutin avulla voidaan lomake-elementille määritellä pikanäppäin, jota painamalla siirrytään kenttään, jonka otsikkoon pikanäppäin on määritelty. Yleensä pikanäppäimen kanssa pitää painaa myös jokin toinen näppäin. Tämä näppäin riippuu jonkin verran käytettävästä käyttöjärjestelmästä ja selaimesta. Kts. accesskey (MDN)

<p><label
accesskey="N" for="name">Nimi:
</label> <input id="name" type="text"
name="Nimi" value="Etunimi Sukunimi" /></p>

input-elementti

input-elementti on hyvin monipuolinen lomakkeella käytettävä elementti, jonka type-attribuutin arvoa vaihtamalla saadaan käyttöön erilaisia lomake-elementtejä.

Yleiset ominaisuudet

name-attribuutilla voidaan antaa kontrollille nimi. Nimen antamisen hyöty tulee näkyviin vasta lomakkeen käsittelyn yhteydessä, koska kontrollin arvo lähetetään lomakkeen tiedot käsittelevälle ohjelmalle muodossa name=kentan+sisalto .

value-attribuutilla voidaan kontrollille antaa oletusarvo. Lomakkeen lataamisen yhteydessä value-attribuutin arvo näkyy valmiiksi kontrollissa. Valintaruudun ja valintanapin yhteydessä value-attribuutin arvo välitetään lomakkeen tiedot käsittelevälle ohjelmalle.

Seuraavassa lyhyt esimerkki name- ja value-attribuutin käytöstä. Esimerkissä name-attribuutin arvona on kokonimi ja value-attribuutin arvona on teksti ”Etunimi Sukunimi”.

Graphic2

Kuten oheisesta kuvasta voi päätellä, niin value-attribuutin arvo näytetään oletuksena lomakekentässä.

<input type="text" name="kokonimi" value="Etunimi Sukunimi" />

Jos edellisen esimerkin lomakkeen tiedot lähetetään käsittelevälle ohjelmalle oletusasetuksilla, niin tiedot ovat seuraavaa muotoa (name=value):

kokonimi=Etunimi+Sukunimi

size-attribuutilla voidaan määritellä kontrollille pituus. Pituus annetaan pikseleinä, mutta jos attribuutin type arvona on text tai password, niin arvo tarkoittaa kenttään mahtuvien merkkien lukumäärää.

id-attribuutilla voidaan elementille antaa yksikäsitteinen id-nimi, johon voidaan viitata esimerkiksi label-elementissä.

tabindex-attribuutilla voidaan elementeille määritellä tabulointijärjestys eli järjestys, jossa kentät aktivoituvat painettaessa tab-näppäintä. tabindex-attribuutin arvoksi voidaan antaa numerot välillä 0-32767.

type-attribuutilla määritellään input-elementin käyttötarkoitus. Mahdollisia type-elementin arvoja ovat text, password, checkbox, radio, submit, reset ja hidden.

Tekstikenttä - text

Graphic3

text-arvo luo oheisen kuvan mukaisen yksirivisen tekstisyöttökentän. Seuraavassa on esimerkki kuvan mukaisen tekstisyöttökentästä.

<p><label
for="email">Email: </label> 
<input id=”email” type="text" name="email" value="Sahköpostiosoite" />
</p>

Syöttökentän pituutta ei ole oletuksena rajoitettu, joten riville voi syöttää tekstiä kohtuullisen paljon. Kentän pituutta voidaan rajoittaa maxlength-attribuutin avulla ja näkyvissä olevan tekstikentän koko lomakkeella voidaan määritellä size-attribuutin avulla. Seuraavassa esimerkissä sotun syöttämistä on haluttu rajoittaa. Sotu sisältää yksitoista merkkiä, joten kenttään halutaan tasan yksitoista merkkiä.

Graphic4
<p><label for="sotu">Sotu: </label>
<input
maxlength="11"size="11" id="sotu"
type="text" name="sotu" value="000000-000A" />
</p>

Salasanakenttä - password

Graphic5

password-arvo luo tekstikentän, johon voidaan syöttää merkkejä siten, että näytöllä merkkien kohdalle kirjoitetaan tähtimerkki (asteriski, *). Tämä ei anna oikeasti mitään salausta kirjoitetulle tekstille, koska kenttään kirjoitettu teksti tullaan lähettämään selkokielisenä lomakkeen käsittelevälle ohjelmalle. Oheisessa kuvassa seuraavan esimerkin mukainen salasanakenttä, johon on syötetty jo salasana.

<p><label for="passwd">Salasana: </label>
<input id="passwd" type="password" name="salasana" value="" />
</p>

Valintaruutu - checkbox

Graphic6

checkbox-arvo tekee elementistä valintaruudun. Valintaruudut ovat neliön muotoisia kenttiä, joita käyttäjä voi halutessaan valita päälle tai pois päältä. Ruutuja voidaan valita useampiakin, joten ne eivät ole toisensa pois sulkevia, kuten esimerkiksi valintanapit. Valintaruutuja voidaan valita useampia, joten kaikkien valittujen arvot lähetetään lomakkeen lähettämisen yhteydessä. Seuraavassa esimerkissä on oheisen kuvan mukainen valintaruuduilla toteutettu kysymys. Esimerkistä kannattaa huomata, että kaikkien samaan ryhmään kuuluvien valintaruutujen -attribuutin arvon on oltava sama.

checked-attribuutilla valintaruudulle voidaan määritellä oletusarvo. Tällöin attribuutin arvoksi on laitettava checked.(checked="checked")

<p><label for="henkiloauto">henkilöautolla </label>
<input id="henkiloauto" type="checkbox"  name="tyomatka" value="hauto"
/><br />
<label for="bussi">bussilla </label>
<input id="bussi" type="checkbox" name="tyomatka" value="bussi" checked="checked" /><br/>
<label for="juna">junalla </label>
<input id="juna" type="checkbox" name="tyomatka" value="juna" /><br/>
<label for="pp">polkupyörällä </label>
<input id="pp" type="checkbox"name="tyomatka" value="pp" /><br/>
<label for="mp">moottoripyörällä </label>
<input id="mp" type="checkbox"name="tyomatka" value="mp" /><br/>
<label for="jalan">kävellen </label>
<input id="jalan" type="checkbox" name="tyomatka" value="jalan" /><br/>
</p>

Valintanappi - radio

Graphic7

radio-arvo tekee elementistä valintanapin. Valintanappi on pyöreä kenttä. Käyttäjä voi valita saman ryhmän valintanapeista ainoastaan yhden arvon, koska asetettaessa uusi arvo päälle menee entinen valinta pois päältä. Esimerkistä kannattaa huomata, että kaikkien samaan ryhmään kuuluvien valintanappien -attribuutin arvon on oltava sama. Jos arvo ei ole sama, niin valintanappeja voidaan valita useampiakin ”näennäisesti” samasta ryhmästä.

checked-attribuutilla valintaruudulle voidaan määritellä oletusarvo. Tällöin attribuutin arvoksi on laitettava checked. (checked="checked")

<p>Ikäni on</p>
<p>
<label for="pk20">&lt; 20 vuotta.</label>
<input id="pk20" type="radio" name="ika" value="< 20" /><br/>
<label for="ika2030">20-30 vuotta.</label>
<input id="ika2030" type="radio" name="ika" value="20-30" /><br/>
<label for="ika3040">30-40 vuotta</label>
<input id="ika3040" type="radio" name="ika" value="30-40" /><br/>
<label for="ika4050">40-50 vuotta</label>
<input id="ika4050" type="radio" checked="checked" name="ika" value="40-50" /><br/>
<label for="sk50">&gt; 50 vuotta</label>
<input id="sk50" type="radio" name="ika" value="> 50" /><br/>
</p>

Lähetä-painike - submit

submit-arvo luo painikkeen, jolla lähetetään lomakkeen tiedot käsittelevälle ohjelmalle. Painikkeessa lukeva teksti voidaan vaihtaa value-attribuutin arvoa muuttamalla.

<p><input
type="submit" name="laheta" value="Lähetä kommenttisi" />
</p>

Tyhjennä-painike - reset

reset-arvo luo painikkeen, jolla lomakkeen kentät tyhjennetään ja kenttiin sijoitetaan oletusarvot. reset-painikkeen käyttöä lomakkeella kannattaa harkita tarkkaan, koska käyttävä voi vahingossa tyhjentää täyttämänsä lomakkeen ennen lähetystä. Älä laita lomakkeelle reset-painiketta

<p><input type="reset" name="tyhjenna" value="Tyhjennä lomake"/></p>

Piilokenttä - hidden

hidden-arvo luo piilotetun kentän, jota ei näytetä käyttäjälle selainikkunassa. Piilotettujen kenttien avulla lomakkeella voidaan välittää tietoa, joka on tarpeellista esimerkiksi lomakkeen käsittelyssä, mutta sitä on turha näyttää varsinaisella lomakkeella. Piilokenttään ei kannata sijoittaa mitään ”salaista” tietoa, kuten esimerkiksi salasanoja tai vastaavia, koska kenttä ja sen arvo nähdään sivun lähdekoodista. Seuraavassa lyhyt esimerkki piilokentän käytöstä.

<p><input type="hidden" name="ID" value="L0011"/></p>

Tekstialue - textarea

textarea-elementti mahdollistaa useampirivisen vapaamuotoisen tekstikentän lomakkeella. Elementtiä kannattaa käyttää erilaisten vapaamuotoisten tekstien kirjoittamispaikkana, koska kirjoittaminen useammalle riville on usein mielekkäämpää kuin yhdelle riville.

name-attribuutilla voidaan antaa textarea-elementille nimi. Kannattaa huomata, että textarea-elementillä ei ole value-attribuuttia, vaan oletussisältö kirjoitetaan elementin sisään ohessa olevan esimerkin mukaisesti.

rows-attribuutti määrittelee textarea-elementissä näkyvillä olevien rivien lukumäärän. Tämä ei kuitenkaan rajoita rivien lukumäärää, joille käyttäjä voi kirjoittaa. Jos kaikki rivit eivät mahdu kerralla textarea-elementin sisään, luodaan elementin oikeaan laitaan vierityspalkki.

cols-attribuutti määrittelee textarea-elementissä olevan rivin pituuden. Rivin pituudella tarkoitettaan riville mahtuvien ”keskiarvokirjainten” määrää. Arvo ei kuitenkaan rajoita riville kirjoitettavien merkkien lukumäärää. Jos rivi ei mahdu kerralla textarea-elementin sisään, luodaan elementin alalaitaan vierityspalkki.

Graphic8

tabindex-attribuutilla voidaan elementeille määritellä tabulointijärjestys eli järjestys, jossa kentät aktivoituvat painettaessa -näppäintä. tabindex-attribuutin arvoksi voidaan antaa numerot välillä 0-32767.

<p><label for="desc">Tarkempi kuvaus ongelmasta</label><br/>
<textarea id="desc" name="kuvaus" rows="12" cols="50">
Tähän tarkempi kuvaus asiasta..
</textarea>
</p>

Valintalista - select

Valintalista on lomakkeella yksi- tai useampivalintainen alasvetovalikko. Valintalistan käyttötilanteet ovat usein samanlaisia kuin radiopainikkeilla ja valintalaatikoilla, mutta valintalistat vievät fyysisesti paljon vähemmän tilaa lomakkeelta. Valintalista luodaan select-elementillä ja sen sisään täytyy laittaa vähintään yksi option-elementti, josta muodostuu varsinainen valinta.

select-elementti

select-elementti luo varsinaisen valintalistan rungon, jonka sisään tulevat valinnat toteutetaan option-attribuutilla.

name-attribuuttilla voidaan antaa nimi select-elementille.

size-attribuutilla määritellään näkyvissä olevan listan koko. Koko ei ole eri vaihtoehtojen lukumäärä vaan se on pelkästään näkyvillä olevien vaihtoehtojen lukumäärä. Jos vaihtoehtoja on useampia kuin size-attribuutissa on määritelty, niin elementin oikeaan laitaan luodaan vierityspalkki.

multiple-attribuutilla voidaan mahdollistaa elementin useamman vaihtoehdon valinta aktiiviseksi yhtä aikaan. Jos attribuuttia ole määritelty voidaan elementistä kerrallaan valita vain yksi kohta aktiiviseksi.

tabindex-attribuutilla voidaan elementeille määritellä tabulointijärjestys eli järjestys, jossa kentät aktivoituvat painettaessa tab-näppäintä. tabindex-attribuutin arvoksi voidaan antaa numerot välillä 0-32767.

option-elementti

option-elementillä määritellään valintalistan (select-elementin) sisään tulevat vaihtoehdot. Näkyville tuleva vaihtoehto kirjoitetaan option-elementin sisään eli aloitus- ja lopetus-elementin väliin.

selected-attribuutti ilmaisee onko jokin option-elementillä määritelty kohta valittu aktiiviseksi oletuksena. Attribuutin arvoksi pitää antaa selected. (selected=”selected”)

value-attribuutti antaa oletusarvon kontrollille. Jollei kontrollille ole asetettu mitään arvoa, käytetään sen sisältöä oletusarvona.

Seuraavassa esimerkissä on iän kysymiseen tarkoitettu valintalista. Iän oletusarvoksi on määritelty 20-30 vuotta.

Graphic9
<p><label for="ika">Ikäsi on</label>
<select id="ika" name="ika">
<option value="pk20">&lt; 20 vuotta</option>
<option selected="selected" value="ika2030">20-30 vuotta</option>
<option value="ika3040">30-40 vuotta</option>
<option value="ika4050">40-50 vuotta</option>
<option value="sk50">&gt;50 vuotta</option>
</select>
</p>
Graphic10

Seuraavassa esimerkissä on havainnollistettu valintalistaa, josta voi valita useamman eri vaihtoehdon. Iän kysymiseen tällainen valintalista ei kuitenkaan sovellu. Esimerkki on seuraavaa riviä lukuun ottamatta sama kuin edellä esitetty esimerkki.

<select id="ika" name="ika" multiple="multiple" size="3">

Valintalistan ryhmittely - optgroup

Valintalistan ryhmittelyyn voidaan käyttää optgroup-elementtiä. Elementillä saadaan kätevästi ryhmiteltyä valintoja pienempiin ja selkeämpiin kokonaisuuksiin.

label-attribuutilla määritellään otsikko koko optgroup-ryhmälle.

Graphic11
<p>
<label for="versio">Versio on</label>
<select id="versio" name="ohjelma-versio">
<optgroup label="Word"> 
<option value="Word 6">Word 6</option>
<option value="Word 95">Word 95</option>
<option value="Word 97">Word 97</option>
<option value="Word 2000">Word 2000</option>
</optgroup>
<optgroup label="Excel">
<option value="Excel 5">Excel 5</option>
<option value="Excel 95">Excel 95</option>
<option value="Excel 97">Excel 97</option>
<option value="Excel 2000">Excel 2000</option>
</optgroup>
</select>
</p>

Lomake-elementtien ryhmittely - fieldset

Graphic12

-elementillä voidaan ryhmitellä lomakkeilla olevia kenttiä loogisiksi kokonaisuuksiksi. Ryhmittelyn tarkoituksena on havainnollistaa käyttäjälle lomakkeella kysyttävien tietojen tarkoitusta.

Seuraavassa esimerkissä on käytetty fieldset-elementtiä lomakkeen tietojen ryhmittelemiseen. legend-elementillä kerrotaan kyseisen elementtiryhmän otsikko, joka on sijoitettu ensimmäiseksi elementiksi fieldset-ryhmään. Lomakkeella voi olla muitakin fieldset-ryhmiä

<fieldset><legend>Henkilötiedot</legend>
<label accesskey="N" for="name">Nimi: </label>
<input id="name" type="text" name="Nimi" value="Etunimi Sukunimi" /><br />
<label for="email">Email: </label>
<input id="email" type="text" name="email" value="Sahköpostiosoite" /><br />
<label for="sotu">Sotu: </label>
<input maxlength="11" size="11" id="sotu" type="text" name="sotu" value="000000-000A" /><br />
</fieldset>

Elementtien ryhmän otsikko - legend

Elementtiryhmälle voidaan antaa otsikko legend-elementin avulla.

accesskey-attribuutin avulla voidaan legend-elementille määritellä pikanäppäin, jota painamalla siirrytään kyseisen lomakeryhmän alkuun.

Lomakkeen käsittely

Lomakkeen käsittely

  1. Selainohjelma pyytää palvelimelta lomakesivun HTTP-protokollan mukaisilla otsikkotiedoilla.
  2. Palvelin vastaa selaimelle HTTP-protokollan mukaisilla otsikkotiedoilla, jonka jälkeen tarjoaa WWW-sivun datan eli HTML-koodia.
  3. Käyttäjä täyttää ja hyväksyy lomakkeen. Selain lähettää lomakkeen tiedot WWW-palvelimella suoritettavalle ohjelmalle.
  4. Lomakkeella oleva data käsitellään ohjelman tekijän haluamalla tavalla.
  5. Ohjelma palauttaa käyttäjälle virheilmoituksen tai ilmoituksen onnistumisesta, esim. lomakkeen korjauspyynnöillä tai tulossivun.

Lomakkeen käsittely

HTTP (HyperText Transfer Protocol)

HTTP on protokolla, jonka avulla selain ja WWW-palvelin keskustelevat.

Firefox-selaimen ja WWW-palvelimen välistä HTTP-liikennettä on helppo seurata Firebugilla tai Tamper Data -laajennuksella .

Selain lähettää WWW-palvelimelle pyynnön:

GET /sovellukset/testi.html HTTP/1.1
Connection: keep-alive
Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,video/x-mng,image/png,image/jpeg,image/gif;q=0.2,*/*;q=0.1
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Accept-Encoding: gzip,deflate
Accept-Language: en-us,en;q=0.5
Host: appro.mit.jyu.fi
Referer: http://appro.mit.jyu.fi/
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.4) Gecko/20030624
Keep-Alive: 300
Selaimen lähettämät HTTP-otsakkeet selityksineen
GET /sovellukset/testi.html HTTP/1.0 Pyydetään informaatiota (GET), jonka osoite palvelimella on /sovellukset/testi.html käyttäen HTTP/1.1-protokollaa.
Connection: keep-alive Käsketään pitää yhteys päällä.
Accept: text/xml, application/xml, application/xhtml+xml, text/html;q=0.9, text/plain;q=0.8, video/x-mng, image/png, image/jpeg, image/gif;q=0.2, */*;q=0.1 Luetellaan selaimen ymmärtämät mediatyypit. Kerrotaan myös mitä mediatyyppejä suositaan q-arvojen avulla.
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7 Luetellaan kelpaavat merkistöt.
Accept-Encoding: gzip,deflate Luetellaan tuetut koodaustavat (pakkaus).
Accept-Language: en-us,en;q=0.5 Halutut kielet
Host: appro.mit.jyu.fi Palvelimen nimi
Referer: http://appro.mit.jyu.fi/ Osoite, josta ollaan tulossa (sivu, jolla olevaa linkkiä on klikattu).
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.4) Gecko/20030624 Selaimen tiedot
Keep-Alive: 300Kertoo kuinka monta sekuntia yhteyttä pidetään yllä. Vain HTTP/1.0-protokollassa, mutta käytetään yhteensopivuussyistä. Oikeastaan muoto pitäisi olla Keep-Alive: parametri=arvo.

Palvelin vastaa:

HTTP/1.1 200 OK
Connection: close
Date: Tue, 06 Apr 2004 10:53:18 GMT
Accept-Ranges: bytes
ETag: "2da29-2147-4044819d"
Server: Apache/1.3.27 (Unix)  (Red-Hat/Linux) PHP/4.1.2 mod_perl/1.26
Vary: Accept
Content-Length: 414
Content-Type: application/xhtml+xml; charset=iso-8859-1
Last-Modified: Tue, 02 Mar 2004 12:44:13 GMT

<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/2000/REC-xhtml1-20000126/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="fi" >
<head>
  <title>Testisivu</title>
  <link href="testi.css" rel="StyleSheet" type="text/css" />
</head>
<body>
  <h1>Testiotsikko</h1>
  <p>Testitekstiä</p>
</body>
</html>
WWW-palvelimen vastaus
HTTP/1.1 200 OKStatuskoodi - kaikki kunnossa.
Connection: close Palvelin sulkee yhteyden. Normaalisti yhteys on pysyvä (persistent), jotta selain voi tehdä useita pyyntöä (kuvat, css, javascript jne.).
Date: Tue, 06 Apr 2004 10:53:18 GMT Päivä ja aika, koska vastaus on lähetetty.
Accept-Ranges: bytes Sallitaan tavuina määritellyt pyynnöt joissa halutaan vain osa dokumentista.
ETag: "2da29-2147-4044819d" Tunniste. Tunniste muuttuu dokumenttia muutettaessa.
Server: Apache/1.3.27 (Unix) (Red-Hat/Linux) AxKit/1.62 mod_python/2.7.8 Python/1.5.2 mod_ssl/2.8.12 OpenSSL/0.9.6b DAV/1.0.3 PHP/4.1.2 mod_perl/1.26 mod_throttle/3.1.2WWW-palvelimen tiedot
Vary: Accept-Encoding Vaihteleeko pyydetty resurssi jonkun ehdon mukaan. Tärkeä tieto esim. välimuisteille. Accept-Encoding: esim. erilainen pakkaus. Accept-Language: tarjolla useita kieliversioita. User-Agent: sivun sisältö riippuu selaimesta.
Content-Length: 414 Sisällön koko
Content-Type: application/xhtml+xml; charset=iso-8859-1Mediatyyppi ja merkistö
Last-Modified: Tue, 02 Mar 2004 12:44:13 GMTMilloin viimeksi muutettu.

HTTP-otsikoita voi tutkia tarkemmin esim. seuraavilla ohjelmilla:

HTTP Status Codes

Palvelin palauttaa vastauksessa HTTP-statuskoodin, joka kertoo lyhyesti selaimelle miten pyyntö onnistui ja miten tulee jatkossa toimia. Listassa yleisimmät:

Lisätietoa

Pythonin cgi-kirjasto

lomake.cgi (lomake.txt)

HTML:n erikoismerkit (<, > ja &) pitää muistaa koodata entiteeteiksi. Apuna voi käyttää cgi.escape-metodia. Attribuuttien arvot voi koodata xml.sax.saxutils.quoteattr-metodilla.

URLien kielletyt merkit voi koodata urllib.quote-metodilla.

CGI-ohjelmointi Pythonilla

CGI eli Common Gateway Interface on yksinkertaisin rajapinta WWW-sovelluksien tekemiseen

XHTML-dokumentti Python-kielellä ja CGI-rajapinnan kautta tuotettuna:

#!/usr/bin/python
# -*- coding: utf-8 -*-

print """Content-type: text/html; charset=UTF-8

<!doctype html>
<html>
  <head>
    <title>Malli</title>
  </head>
<body>
  <h1>Tulostetaan Pythonilla:</h1>
  <p>
"""
print "Hello World! Osaatkönä skändejä?"
print """
  </p>
</body>
</html>
"""

Virheilmoitukset ja asetukset

Pythonilla tehtyjen CGI-ohjelmien debuggaamista helpottaa cgitb-moduulin käyttöönotto:

import cgitb
cgitb.enable()

cgitb aiheuttaa virheraporttien näyttämisen www-selaimessa tai niiden tallentamisen tekstitiedostoon.

CGI-ympäristömuuttujat:

import os

print "Content-type: text/plain\r\n\r\n";
for param in os.environ.keys():
  print "%20s: %s\n" % (param,os.environ[param])

cgi-moduuli

item = form.getvalue("item")
if isinstance(item, list):
else:
import cgi
form = cgi.FieldStorage()
user = form.getfirst("user", "").upper()    # Ei hajoa vaikka tulisi useampi arvo
for item in form.getlist("item"):
    do_something(item)

HTML:n vaatimien erikoismerkkien koodaukseen voi käyttää cgi.escape(s[, quote])-metodia.

Lisätietoa: HOWTO Use Python in the web

Templatet ja Jinja

Yhtenäisen sivuston eri sivuilla on usein samankaltaisia osia, jotka joudutaan jokaisella sivulla liittämään includella tai copy&pastella jokaiselle sivulle. Näitä osia ovat esimerkiksi navigoinnit ja autentikoinnista huolehtiminen. Entäpä jos joltain sivulta tärkeitä kuten käyttäjätarkistus unohtuukin?

Templateilla (eli sivupohjilla) saavutetaan seuraavia etuja:

Sivun sisältämää html-koodia ei pidä kirjoittaa suoraan python-ohjelman sisään, koska silloin tuloksena on ylläpitokelvoton koodin ja html:n sekasotku. Pyritään MVC-malliin jossa ohjelman toimintalogiikka (controller) pidetään erossa näkymästä (view) eli www-sivun sisällöstä. Tämä onnistuu helposti käyttämällä templateja. Yksi käytetyimpiä on Jinja2.

Jinja2 documentation

Jinjan koodi erotetaan html-koodista jollakin seuraavista:

Muuttujien arvoja voi muokata Jinjan filttereillä. Filtteri ja muuttuja erotetaan toisistaan |-merkillä. Esim. lista|len palauttaa listan pituuden. Jos automatic escaping ei ole päällä niin jää omalle vastuulle varmistaa, että kaikkien muuttujien sisältö kelpaa html:ään. Tämä voidaan varmistaa e-filtterillä: muuttuja|e

Jinjan for-loopissa voi käyttää apuna loop-muuttujan arvoja. Esim. loop.index antaa 1-alkuisen kierroksen indeksin ja loop.index0 0-alkuisen. Jinja silmukkaa ei voi breakata.

Jos tarvii Jinjassa luoda uusia muuttujia niin se on tehtävä set-komennolla:

{% set muuttuja = arvo %}

Katso jinja.cgi-esimerkki (Lähdekoodi, Jinja template)

Toinen jinja-esimerkki (Lähdekoodi, Pohjatemplate, Toinen template)

Python, merkistöt ja erikoismerkit webissä

Erikoismerkit webissä

erikoismerkit (<, >, &) hoituvat automaattisesti jos käyttää dom-rajapintaa tai jinjan templateja autoescape-ominaisuuden ollessa päällä. Jos ei käytä niin käyttäjän syötteet on ajettava cgi.escape-funktion läpi. Ei kuitenkaan molempia, koska silloin esim. <-merkki esitetään koodatussa muodossa &lt; eikä <.

Linkkeihin täytyy erikoismerkit (<, >, %amp;, välilyönti, ä,ö,å jne) koodata vielä erikseen, koska linkeissä on omat rajoituksensa. Tämä hoituu urllib.quote-funktiolla.

http://blog.notdot.net/2010/07/Getting-unicode-right-in-Python

http://www.ohjelmointiputka.net/oppaat/opas.php?tunnus=python_l2

http://www.joelonsoftware.com/articles/Unicode.html

Käyttäjien kommentit

Kommentoi Lisää kommentti
Kurssimateriaalien käyttäminen kaupallisiin tarkoituksiin tai opetusmateriaalina ilman lupaa on ehdottomasti kielletty!
http://appro.mit.jyu.fi/web-sovellukset/luennot/luento6/
© Tommi Lahtonen (tommi.j.lahtonen@jyu.fi) <http://hazor.iki.fi/>
2016-02-16 11:15:28
Informaatioteknologia - Jyväskylän yliopiston informaatioteknologian tiedekunta