Tegnsæt på web II
Resumé
Af Kell Sønnichsen, UNI-C19/10 2004
Når en bruger trykker på 'Send'-knappen i en formular, sendes en række tegn til serveren. Hvordan sikrer vi os, at data indtastet i en formular indeholder det samme, når det når frem til serveren og databasen, som det brugeren ser, når han taster ind? Hvilke tegn sendes, og hvordan fortolkes de? Hvilket tegnsæt er de kodet med?
I den forrige artikel om tegnsæt på web så vi på, hvordan man kunne vise forskellige bogstaver – f.eks. æ, ø, å sammen med kyrilliske tegn - på samme side, altså hvordan man håndterer tegnsæt som afsender. I denne artikel kigger vi på, hvad man kan gøre for at få indtastede data helskindet frem til server og evt. database fra en indtastningsformular, altså sikre sig et bestemt tegnsæt som modtager.
Problemet kan illustreres med et eksempel, hvor data på serveren bliver fortolket som hhv. Latin-1 (ISO-8859-1) og UTF-8. Bemærk, at der bliver sendt det samme i de to tilfælde (de hexadecimale værdier er de samme), men at det er fortolkningen på serversiden, der er forskellig.
Der er to strategier til at sikre sig, at modtager og afsender er enige om indholdet af data:
- Vi kan finde ud af, hvilket tegnsæt, brugeren har brugt ved indtastningen.
- Vi kan påtvinge brugeren at benytte et bestemt tegnsæt.
Desværre er udgangspunktet dårligt, idet man ikke kan blive 100% sikker, men man kan forbedre sine chancer.
Mange af vores problemer med at vise tegnsæt i forrige artikel blev løst ved at angive passende headere, som fortalte browseren, hvordan data skulle fortolkes. Det er oplagt at forsøge, om vi kan benytte de headere, som browseren sender tilbage, når en formular udfyldes, til at finde ud af, hvilket tegnsæt, der er brugt. Noget for noget!
Desværre skal man ikke regne med et fornuftigt bytteforhold. Browseren har faktisk ikke nogen mulighed for at fortælle, hvilket tegnsæt, der er brugt ved indtastning i formularen. Da man lavede HTTP-protokollen, som er den, der benyttes til at transportere vores hjemmesider og formularindhold over internettet, glemte man at definere en header, der fortalte tegnsættet for formulardata. Ups …
Der findes en header, Content-Type, som sættes ifm. en afsendelse af formulardata vha. POST metoden, men den angiver desværre kun, at der er tale om formulardata (application/x-www-form-urlencoded) og fortæller ikke, hvilket tegnsæt, der er brugt.
Så vi må finde på noget andet.
Når vi ikke kan få at vide, hvilket tegnsæt, der er brugt, bliver vi nødt til at gætte. Både information om brugerens browser samt opbygningen af selve formulardata kan give nogle gode gæt på, hvilket tegnsæt, der er brugt.
Der er specielt to oplysninger om browseren, der kan hjælpe os: HTTP_USER_AGENT, der fortæller om brugerens browser – herunder sprogversion – og HTTP_ACCEPT_LANGUAGE, der fortæller, hvilket sprog brugeren foretrækker. Begge disse oplysninger kan man ”kigge på” og derudfra forsøge at gætte, hvilket tegnsæt, der bruges. Specielt mellem de forskellige ISO-8859 tegnsæt kan denne metode bruges, idet disse ofte følger sprogene:
|
ISO-8859-1 |
Latin-1: Vesturopa |
|
ISO-8859-2 |
Latin-2: Central- og Østeuropa (bl.a. tjekkisk) |
|
ISO-8859-3 |
Latin-3: Sydeuropa (bl.a. spansk) |
|
ISO-8859-4 |
Latin-4: Nordeuropa (bl.a. islandsk og baltisk) |
|
ISO-8859-5 |
Kyrillisk (russisk) |
|
ISO-8859-6 |
Arabisk (delmængde) |
|
ISO-8859-7 |
Græsk |
|
ISO-8859-8 |
Hebræisk |
|
ISO-8859-9 |
Latin-5: Tyrkisk |
|
ISO-8859-10 |
Latin-6: Nordisk (afløser Latin-4) |
|
ISO-8859-11 |
Thai |
|
ISO-8859-13 |
Latin-7: Baltisk |
|
ISO-8859-14 |
Latin-9: Samisk |
|
ISO-8859-15 |
Latin-1 med bl.a. €-tegn tilføjet |
Men selv om man ud fra browseroplysningerne kan se, hvilket sprog, brugeren benytter/foretrækker, så vil vi fortsat have en usikkerhed omkring tegnsættet. F.eks. vil en russer oftere benytte KOI8-R tegnsættet fremfor ISO-8859-5, hvis han da ikke bruger UTF-8. Samme problemer kan man have i Nordeuropa, hvor ikke mindre end 4 tegnsæt indenfor ISO-8859 familien kan benyttes. Og så er der hele familien af Windows tegnsæt (1250-1257), som også bruges, men de ligner dog meget ISO-8859 tegnsættene. Endelig er der mange brugere, der – f.eks. fordi de vil have den seneste browser – uanset sprog benytter en engelsk browser, således at oplysningerne om browseren giver en forkert indikation af brugerens sprog.
Så vi bliver nødt til at kigge på de formulardata, der sendes fra browseren, dvs. kigge på de talværdier, der sendes og vurdere derudfra, hvilket tegnsæt, der benyttes. Når der sendes værdierne (hexadecimalt) D5 A9, skal det så opfattes som et armensk lille 'to' eller som Õ©? [1]
Det generelle tilfælde er meget vanskelligt, men hvis vi holder os til dansk, er vi mere heldige, idet vi her i praksis kun har at gøre med enten ISO-8859-1, Windows-1252 eller UTF-8. Dog kan vi ikke helt se bort fra, at der kan komme data fra en gammel Macintosh, som fortsat benytter Mac OS Roman tegnsættet. De to første er så ens, at forskellen kan ignoreres, dvs. vi skal kun skelne mellem Latin-1, UTF-8 og MacRoman, og her er det kun på ”specialtegnene” æ, ø og å, der er forskelle.
- Hvis teksten indeholder flere C3 værdier, er det et godt bud, at der er tale om UTF-8, hvor den næste værdi så vil afgøre, hvilket specialtegn, der er tale om (f.eks. C3 A6: æ). Vi skal dog passe på med ikke helt at afskrive Latin-1 muligheden, hvor C3 er koden for Ã.
- Tilstedeværelsen af Latin-1 koderne for æ, ø og å (hhv. E6, F8 og E5) være et godt indicium for brugen af Latin-1, idet disse koder alene ikke angiver en gyldig UTF-8 kodning.
- MacRoman er kendetegnet ved, at æ, ø og å har koderne BE, BF og 8C. Især 8C og 81 (Å) er gode kendetegn, idet ingen af disse koder angiver brugbare tegn i Latin-1 eller UTF-8.
Med en vis ret kan man spørge, om der er grund til bekymring? Langt de fleste formularer virker jo, og æ, ø og å bliver overført smertefrit. Og det er også korrekt, fordi heldet er med os:
De fleste browsere sender data i samme tegnsæt som siden, hvorpå formularen forekommer.
Da de fleste sider er lavet med Latin-1 som tegnsæt, så kan vi både se og skrive æ, ø og å. Og langt de fleste servere og CGI-scripts til modtagelse af formulardata har det da også fint med Latin-1. Så vi kan til dels stole på heldet. Vi behøver ikke at kigge nærmere på formulardata for at have et godt gæt på tegnsættet.
Prisen er, at vi ikke kan bruge tegn fra f.eks. Latin-2 tegnsættet, hverken på siden, hvor formularen forekommer, eller i formularen. Men det ved brugeren ikke, så vi kan godt risikere, at en bruger indtaster tegn fra et andet tegnsæt. Og så er heldet brugt op: tegn, der ikke kan repræsenteres, bliver sendt som '?' (3F), hvilket kan ses af dette eksempel. Vi har ikke en chance for at gætte, hvad brugeren har ment.
Dette problem opstår ikke, hvis vi benytter UTF-8 som tegnsæt. Ved at lave siden i UTF-8 vil (de fleste) browsere sende formulardata tilbage i UTF-8, og så har vi ikke ovenstående problem med mistede tegn. Til gengæld er det ikke alle servere og CGI-scripts – deriblandt det meget udbredte og populære FormMail program – der fungere med UTF-8 som input.
Tommelfingerreglen om data-tegnsæt er lig med side-tegnsæt holder dog ikke helt ved upload af filer. Stærkt afhængigt af browserversionen (helt ned til sidste ciffer i versionen af Internet Explorer) opfører browserne sig forskelligt ved upload af filer. Nogle uploader med filnavn i Latin-1 uanset sidens tegnsæt, mens andre gør som ved de øvrige formularfelter, nemlig benytter samme tegnsæt som formularsiden. Dette kan have ubehagelige konsekvenser, hvis der f.eks. indgår æ, ø eller å i filnavnet.
Hidtil har vi ikke været for succesfulde med hensyn til at prøve at finde ud af, hvilket tegnsæt, browseren sender med. At kigge på data og gætter derudfra er besværligt, og at de fleste browsere sender data fra formularen med samme tegnsæt, som siden er skrevet i, er en udokumenteret erfaring. Kan vi vende bøtten og bestemme, hvilket tegnsæt, browseren skal sende med?
Ja, det kan vi godt – til dels. Der findes en attribut, som angiver et accepteret tegnsæt:
accept-charset=”UTF-8”
Denne attribut kan sættes på <FORM>-tag'en og fortæller browseren, at data skal sendes i det angivne tegnsæt. Det er en del af HTML 4.0 standarden, men desværre er det også her browserafhængigt, om den understøttes. Det kan (måske) ses af dette eksempel.
I praksis er den mest brugbare løsning at lade heldet råde, dvs. satse på, at data-tegnsættet er det samme som side-tegnsættet. Vi kan vælge mellem to tegnsæt:
- Latin-1. Hermed opnås færrest problemer med eksisterende standard-scripts, f.eks. FormMail. Ulempen er, at indtaster brugeren tegn fra et andet tegnsæt, vil det blive overført som '?', og vi har ikke en chance for at gætte, hvad brugeren mente.
- UTF-8. Her kan vi sikre os, at der ikke tabes data fra brugerens indtastning i formularen. Alle tegn, som brugeren kan finde på at skrive, overføres. Til gengæld kan det give problemer på serversiden, hvor ikke alle programmer er skrevet til at kunne håndtere UTF-8.
Vi kan give browseren et hint om det tegnsæt, vi ønsker, ved at bruge accept-charset attributten, men understøttelsen af dette er browserafhængigt.
Mest sikkerhed får vi ved at kombinere de to ovenstående (held og hint) og desuden undersøge data for specielle tegn, hvorfra vi kan gætte tegnsættet. Men det er klart også mest besværligt.
Noter
- Præcis hvordan man "kigger på" de hexadecimale værdier af formulardata afhænger stærkt af, hvilket programmeringssprog, man benytter, og falder uden for fokus af denne artikel. Hvis man benytter Perl, så er
ord()funktionen et godt redskab.
Links
- Tegnsæt på web - første artikel om problemer med forskellige tegnsæt.
- Alan Wood's Unicode Resources – Megen information om hvordan man kan bruge tegnsæt på nettet og i programmer
- The ISO 8859 Alphabet Soup – En oversigt over de mange forskellige ISO-8859 tegnsæt, der findes. Eller rettere: fandtes, for siden er sidst opdateret i 1998, og der er kommet en række flere tegnsæt til siden.
- HTTP protokollen – World Wide Web Consortiums (W3C) specifikation på HTTP protokollen. Advarsel: Meget teknisk.
- HTML 4.0 / Forms – W3C specifikationen af formularer i HTML 4.0 standarden. Advarsel: Meget teknisk.
- CGI Programming on the World Wide Web – En god O'Reilly bog, hvis indhold på trods af alderen (1996) fortsat er relevant. Den er p.t. udgået fra forlaget, så den findes on-line i stedet.

Udskriv…
Hjælp til udskrift
Om…
Nyhedsbrev
Sitemap
Teknik
Skriv til
RSS
Søg
