AJAX og Æ,Ø,Å.

5. Maj 2007, Kl. 02:07:34

I den tid jeg har arbejdet hos Reklamebureauet ReFocus A/S, har min interesse for AJAX for alvor taget til. Med en god blanding af prototype og Script.aculo.us og andre visuelle scripts, har vi mulighed for at lave hjemmesider, der ligner og fungerer mere og mere som "almindelige" dekstop applikationer - Men der er et catch eller flere!

Et af de første problemer jeg hørte om, var problemet med browsers back-buttons, hvilket der heldigvis findes en løsning på - og lad os ikke glemme, at dette faktisk kun finder sted, når vi bruger AJAX til navigation, eller fjerner/opdaterer et element, så det gamle indhold forsvinder.

Alex Bosworth har skrevet et par artikler om diverse problemer, som folk enten overser eller ikke kender til - Meget interessant og relevant læsning, for folk der vil igang, eller er igang med AJAX.

AJAX og Æ,Ø,Å

I de to nævnte artikler ovenfor, kan du læse meget mere om diverse små problemer. Jeg har i mellemtiden fundet mit eget problem - og det er der nu mange der har, hvis man googler det lidt. Problemet er Æ, Ø, Å og muligvis også andre specielteng i forbindelse med request i AJAX.

I resten af denne post vil jeg tage udgangspunkt i at lave et request med prototype's AJAX objekt.

Men prototype, kan vi lave et AJAX-request på følgende måde:

var url = 'some-file.php';

var pars = 'action=MyActionQuery';



new Ajax.Request(url,{method:'post', postBody:pars});

Vi kan også definerer en eventhandler funktion til at hånterer requestet. Dette gøres med Prototype, ved at definerer funktionen, og tilføje denne til onSucess-propertien, således:

var mySuccess = funktion(request) {

   //gør noget med responset fra requestet

    alert(request.responseText);

}



new Ajax.Request(url, {method:'post', postBody:pars, onSuccess: mySucess});

Problemet er nu, at hvis det respons vi modtager, indeholder Æ, Ø eller Å, vil disse tegn komme til at se rimelig underlige ud, hvis du bruger det dansk tegnsæt ISO-8859-1. Grunden til dette er, at request-metoden (som sendes som XML) som standard benytter UTF-8!

Løsningen kan findes ganske simpelt ved at sætte det korrekte charset i den action fil du benytter (some-file.php i ovenstående).

Jeg har kun prøvet dette af i PHP, men her kan det lade sig gøre, hvis du i starten af filen indsætter følgende:

header('Content-Type: text/html; charset=ISO-8859-1');

Herefter kan du bruge Æ, Ø og Å lige så tosset du vil, og de vil blive vist om forventet gennem dit AJAX request.

Skal du bare sende en enkelt streng, kan du nøjes med at benytte PHP's UTF8 dekoder: string : utf8_decode(string). Du kan læse mere om korrekt brug af tegnsæt her.


37 kommentarer

Lars Lars
#1 →

Hej Simon,

Tak for en god artikel. Men hvad hvis man gerne vil sende æ ø å til php scriptet via POST? Jeg får mærkelige værdier lige meget hvilket charset jeg bruger i både php filen og js filen.

Kan du hjælpe?


Simon Jensen Simon Jensen
#2 →

Hej Lars,

Godt du spørger - så kan vi lige få det med. Det korte svar er: Brug JavaScripts escape() funktion.

For at sætte tingene i perspektiv, så bruger jeg f.eks. POST og AJAX når jeg kommenterer denne post - igen benytter jeg prototype´s JavaScript framework til at få fat i de forskellige "tekst felter" mm. hvilket vi via en ID-parameter kan gøre såleds:

var name = $("name").value;

Indeholder name, altså værdien i tekstfelter med ID="name", Æ, Ø eller Å, kan vi overfører disse til et PHP script, uden problemer, ved at benytte JavaScript funktionen escape().

escape() funtionen enkoder din streng, så den f.eks. kan sendes via XML uden at blive "misforstået" i den anden ende.

Eks:

escape("Æ") = %C6
escape("Ø") = %D8
escape("Å") = %C5

Blev det for forvirende, så bare tag det korte svar i toppen ;)


Jan Nielsen Jan Nielsen
#3 →

/* Change the encodingprocess in prototype */
encodeURIComponent = escape;


Simon Jensen Simon Jensen
#4 →

Det kunne man også, hvis man er sikker på at det ikke har nogen indvirkning andre steder.

En endnu nemmere løsning, i hvert fald hvis man skal posterer, er at serializerer hele formen. Følgende er et eksempel fra prototypes API beskrivelse af metoden serialize - Prøv selv herunder:

User info






Fed siden, jeg faldt over... men load tid på 7-10 sek. Det er sku ikke godt nok. =)

Det kan godt være din server slipper for lidt arbejde med AJAX, men når du har så meget at load, bliver det slemt. 33 sekunder for at test din site på websiteoptimization.com

Connection Rate Download Time
14.4K 238.61 seconds
28.8K 124.80 seconds
33.6K 108.55 seconds
56K 69.53 seconds
ISDN 128K 28.92 seconds
T1 1.44Mbps 12.56 seconds

Håber du kan bruge det til noget? =)


Simon Jensen Simon Jensen
#6 →

Hehe ... ja, det er sandt. Og så skal den vidst heller ikke ses i IE 6!

Begge ting, noget jeg godt ved ... og nok også noget jeg helt sikkert bør få gjort noget ved med tiden.


IE er sku heller ikke godt, altid brugt firefox. =)

Sad lige og afluret dine javascripts, hvis det er okay. =) Har nemlig aldrig brugt AJAX selv, men synes det var på tide at lege lidt med det. Jeg synes at resultatet er blevet godt, har altid synes AJAX var noget lir. Hvilket det også er, men det er noget godt lir.

 


Simon Jensen Simon Jensen
#8 →

AJAX kan være godt ... det kan være en kunst at bruge det fornuftigt. Personligt er jeg bliver bidt af ideen, og ikke mindst af alle de fancy effekter, man ofte vil bruge i sammenhæng hermed. Men som med alt andet JavaScript, så skal der tages højde for alle de forskellige browsere. I den forbindelse vi l jeg foreslå prototype, som beskrevet tidligere, da jeg synes det klarer jobbet godt.


coolyo coolyo
#9 →

Simon Jensen...

jeg ville høre om du har en løsning på mit problem mht. når jeg echo'er javascript kode via php (sammen med ajax) så bliver min javascript kode ikke udført, kun hvis jeg går til php filen direkte og ikke igennem andre php scripts, includes og ajax.


Simon Jensen Simon Jensen
#10 →

Hvis jeg forstå dig ret, kan du ikke få lov at udføre et eksempel som dette:

<?php
echo "<script type='text/javascript'>";
echo "function test() { alert('Dette vil ikke blive vist');";
echo "</script>";
?>

eller dette:

<?php
echo "<script type='text/javascript' src='myJS.js'></script>";
?>

Kan ikke lige huske hvor jeg har læst det ... men en løsning på ovenstående er, at definerer dine JavaScript funktioner på følgende måde:

<script type="text/javascript">
test = function() { alert('Dette VIL blive vist!'); }
</script>

Du kan ligeledes ikke benytte eksterne scripts, altså vha. src parameteren. Jeg bruger selv en funktion, der læser indholdet af eksterne scripts, som er defineret på ovenstående måde, for derefter at udskrive disse i en <script>-blog som jeg kan udskrive vha. echo.

Yderligere skal du sikre dig at evalScripts er sat til true, på dit AJAX-kald (sådan er det i Prototype anyways). Og endeligt, kan du (selvfølgeligt) ikke bruge dine scripts, før de er blevet loaded.


coolyo coolyo
#11 →

Er det muligt at snakke med dig live :> ? jeg er meget dårlig til at formulere mig.

 


Simon Jensen Simon Jensen
#12 →

Det kan vi da godt finde ud af ... Jeg skal godt nok på ferie i morgen, men er tilbage om en uge - Så kan vi lige skrives ved og tage den derfra (jeg kan sende dig en mail, hvis det er i orden).


Coolyo Coolyo
#13 →

er du velkommen til :) og go ferie!


Joseph Joseph
#14 →

http://dnohr.dk/blog/79/Http-Compression-GZip-Deflate.aspx
http://httpd.apache.org/docs/2.0/mod/mod_deflate.html

Jeg sad og tænkte på, din side bruger jo mega lang tid på at load, hvorfor ikke prøve at bruge GZip til at få load time ned?

Også lige til sidst, der er sku så mange måder at blogge på. :P


Alf Georg Østebrøt Alf Georg Østebrøt
#15 →

Hei

Sliter med ÆØÅ, AJAX og MySQL. Sender asynkront via GET og POST for å lagre i MySQL-database, men æøå lagres ikke rett i basen. Erstattes med andre tegn. Responsen fungerer ellers fint når den sendes tilbake til en nettside.  Vet ikke hva jeg skal gjøre for å få æøå riktig inn i databasen. Kan du hjelpe en nordmann?

 

Alf Georg


Simon Jensen Simon Jensen
#16 →

Måsle det har noget at gøre med det charset du har indstillet databasen til at bruge?

Hvis den bruger et charset som ikke understøtter ÆØÅ, så vil de nok komme til at se lidt underlige ud. Jeg bruger selv "UTF-8 Unicode (utf8)" og det virker fint.

Bruger du escape()-funktionen i forbindelse med AJAX, som beskrevet i posten herover?


Alf Georg Østebrøt Alf Georg Østebrøt
#17 →

Ja, nå fungerer det fint! kombinasjonen escape() og header(...) var det som skulle til! Tusen takk!!!

Alf Georg


Alf Georg Østebrøt Alf Georg Østebrøt
#18 →

Hei!

Jeg har mer problemer med ÆØÅ og det hjalp å spørre siste gang, så jeg prøver igjen:

Bruker scriptaculous sin Ajax.InPlaceEditor. Her blir det igjen trøbbel med æøå. Har prøvd både med escape(value) og decodeURIComponent(value), men disse bokstavene lagres feil i basen. escape() gir følgende feilmelding fra prototype:

malformed URI sequence

var value = pair[1] ? decodeURIComponent(pair[1]) : undefined;

Etter søk på nettet får jeg i grunnen bare disse to forslagene til løsning. Har du noen andre tips


Hej! Har fulgt jeres kommentare en del og lært lidt men nu har jeg også et problem med AJAX dog sammen med ASP.

I min database er alle tegnene gode nok men har en edit del hvor det skal smides i nogle inputs der går det galt. Alle tegnene bliver vist som kasser :S

Jeg har sat charset på siden hvor AJAX optræder til ISO-8859-1 så den skulle være iorden men det virker stadig ikke. Så håber på lidt hjælp fra jer :)

Siden er angivet som min hjemmeside: http://e-x-e.dk/djexe/

For at kunne se/bruge editdelen skal i logges ind det gøres under admin med brugernavn=test og adgangskode=test

Søg f.eks. efter ø og vælg en post.


Fik det til at virke med lidt replaces før det skulle gennem AJAX. Tak for en god blog!


Simon Jensen Simon Jensen
#21 →

Hejsa alle ... det lader jo til at I finder ud af det meste, helt af jer selv ;) Super!

Alf G.: Jeg var faktisk ikke klar over, at denne funktionalitet også var lavet af Script.aculo.us - Har du læst dokumentationen til  Ajax.InPlaceEditor? I denne findes også dette link, som måske kan være behjælpelig? Jeg må indrømme jeg har ikke selv prøvet det af - andre der har leget med denne fukntionalitet?


Kold Kold
#22 →

Det er ikke header('Content-Type: text/html; charser=ISO-8859-1');

Men derimod header('Content-Type: text/html; charset=ISO-8859-1');

 


Simon Jensen Simon Jensen
#23 →

Det er rigtigt :) Fejlen rettet...


Simon Jensen Simon Jensen
#24 →

Alf G.: Jeg har nu haft leget lidt med Ajax.InPlaceEditor - og fået det til at virke med æ,ø og å. Her er en metode - forestil dig, at du vil redigerer en kommentar i et <div id="comment">:

JavaScript funtionen:

editComment() = function() {
var callback = function(form) {
return 'action=saveComment&' Form.serialize(form);
}
   
var url = 'actionsFile.php';
var editor = new Ajax.InPlaceEditor("comment", url,{rows:7, cols:80, callback: callback});

editor.enterEditMode('click');
}

Jeg benytter, som det beskrives på script.aculo.us, en callback function, som serializerer mit redirede textfelt. Når jeg så trykker "ok" bliver filen "actionFile.php" kaldt, med parameterne som vi laver i callback-funktionen.

Action i actionFile.php:

if($_POST["action"] == "saveComment") :
    $comment = $_POST["value"];
    $comment = utf8_decode($comment);
    //save in DB or something...  
    echo $comment;
endif;

Callback funktionen får selve formen tilsendt, når denne serializeres kommer den til at se ud på nogen lunde denne måde:

value=hvad%20ever%20you%20have%20written

Jeg modtager altså indholdet i actionFile.php ved at "lede" efter $_POST["value"] parameteren. Denne er nu UTF8 enkodet, så jeg dekoder den med php funktionen utf8_decode() og så er alt godt igen :) - Håber du kan få det til at virke.


Alf Georg Østebrøt Alf Georg Østebrøt
#25 →

Hei

Takker veldig mye for hjelp. Da jeg føyde til utf8_decode kom æøå på plass. Men så skapte andre tegn problemer. Men dette ser ut til å fungere:

function redigernavn(obj) {
    var url = "server/rediger.php";
    new Ajax.InPlaceEditor(obj, url, {
        cancelText:"Avbryt",
        savingText:"Lagrer...",
        size:"10",
        clickToEditText:"Klikk for å endre",
        callback: function(form, value) {return 'personID=' obj.id '&navn=' encodeURIComponent(value) },
        onComplete: function() { hent('server/hent_brukere.php', visElevliste, 'NULL') }
        });
}

... php-fila har:

$navn = htmlentities(utf8_decode($_POST['navn']));

Vet ikke om jeg har helt kontrollen på hva som foregår her, men det ser ut til å fungere.

Må studere ditt forslag nærmere. Kunne jeg på en enkel måtte fått inn serialize.Form i min funksjon? Bruker ellers http://developer.yahoo.com/yui/.

 

 


Alf Georg Østebrøt Alf Georg Østebrøt
#26 →

Så forresten av htmlenteties ikke var noen god ide, da det fører til kluss med alfabetisering. mysql_escape_string er vel bedre? Eller det beste er nok å bruke regulære uttrykk?


Simon Jensen Simon Jensen
#27 →

mysql_escape_string er altid godt at bruge, når du skal arbejde med en database - det øger sikkerheden lidt, men det kan ikke hjælpe dig med noget i forbindelse med tegn-problemer...

Virker utf8_decode($_POST['navn']) ikke godt nok? Du kan evt. smide en mysql_escape_string rundt omkring ...


Jannik Jannik
#28 →

Nu har jeg kæmpet med dette problem i et par timer og siden jeg stadig ikke har fundet en løsning på problemet i IE bliver jeg nødt til at spørge dig til råds:

Jeg benytter mig at scriptaculous og prototype og indtil i dag (i dag kom dagen hvor æøå blev nødvendigt) har jeg levet fint med dette til asynkront save vha. form.serialize (se kodebilag).

Men men men, hvordan er det nu lige jeg håndterer ÆØÅ? Som du kan se har jeg forsøgt at ændre encoding til ISO frem for UTF-8 og det virker faktisk fint i UTF-8 om end jeg måske foretrækker UTF-8. IE ser dog ud til at ignorere denne encoding og gemmer således post som UTF-8, så det ser mærkeligt ud under ISO encoding. What to do?

	ajaxSubmit = function()
	{
	var target = 'info';
	var url = 'write/editPage.asp';
	var pars = Form.serialize('edit_page');
	var myAjax = new Ajax.Request(url, {
		asynchronous:true,
		method:'post',
	    encoding: 'ISO-8859-1',
	   	parameters: pars,
		onComplete: function() {new Effect.Highlight('saved', {duration: 2});}
		});
	}

Simon Jensen Simon Jensen
#29 →

Nu er jeg ikke noget speciel haj når det kommer til ASP - men har du ikke mulighed for, på serveren, at en-/de-code hvad du sender hertil?

I PHP findes der utf8_decode(string) og utf8_encode(string) - måske ASP har noget lignende?

 


Hej
Jeg har siddet med store æøå-problemer, men tror jeg har fundet årsag og - løsning!

Jeg brugte først GET til at sende data med. altså overførte data direkte i min url til xmlhttprequest.

Det virkede i firefox.
Det haltede i Opera
Det f*ckede helt op i IE.

Så skiftede jeg til POST
(Se fx eksempel her: http://www.openjs.com/articles/ajax_xmlhttp_using_post.php )
- og nu fungerer det upåklageligt over hele linjen!

Det ser altså ud som om, at IE på en eller anden måde får f*cked æøå op når man bruger GET.

Håber det kunne hjælpe!
Mvh
Christian Liljedahl


David David
#31 →

Hej

Jeg har søgt på nettet efter en domæne søge funktion, men kan ikke rigtigt finde noget der virker.
Jeg har en oscommerce shop og ville tilføje den heri.
Men jeg er ikke helt klar over hvordan det virker og hvad det er.
Er det ajax den skal bruge eller er jeg helt ved siden af.

Jeg kender ikke noget til ajax, men hvis jeg ved hvad der skal bruges kan jeg bedre finde det.
Håber du / i ved noget om det.

Hilsen David


Simon Jensen Simon Jensen
#32 →

Hej David,

Umiddelbart lyder det du søger efter, noget lignende en Google søgning på hele dit domæne?

Google har jo faktisk lave en sådanne søgemaskine, som man forholdsvis nemt kan tage og bruge på sit site.

Læs mere her: http://www.google.com/coop/cse/


David David
#33 →

Hej Simon

Nej det er ikke sådan en jeg mener.
Jeg vil kunne søge efter ledige domæner, og se vilke der er mulige at få.
Den skal være på en ny side jeg er ved at lave, men stadigvæk en oscommerce side, muligvis også på en html side.
Hvis jeg da kan.


Simon Jensen Simon Jensen
#34 →

Ahhh ... så er jeg med.

Jeg kender detsvære ikke nogen gratis/opensource versioner, men jeg faldt lige over denne: http://www.domjax.com/

Der er et link til køb af kildekoden i bunden, hvis det kunne være en mulighed.


David David
#35 →

Jeg har fundet en gratis, men ved ikke om den virker, den kan ses her http://addons.oscommerce.com/info/1706
Det er en pakke man instalere i shoppen, jeg har prøvet med en tidligere, men den fik jeg ikke til at virke, men ville lige poste denne hvis der var nogen der kunne bruge den
Jeg skal selv have den afprøvet.


Simon Simon
#36 →

Man skal heller ikke overdrive med fede funktioner som der er på denne her site. No wonder den er så langsom.


Simon Jensen Simon Jensen
#37 →

Overdrive? Hvor mange "funktioner" er det lige du ser Hr. Simon fra test.dk??


Skriv den næste kommentar