Python CGI-Script versteht keine Umlaute

Sockets, TCP/IP, (XML-)RPC und ähnliche Themen gehören in dieses Forum
snakeseven
User
Beiträge: 405
Registriert: Freitag 7. Oktober 2005, 14:37
Wohnort: Berlin
Kontaktdaten:

Mittwoch 3. Mai 2006, 11:27

Hi,
ich habe mir einige Threads zu diesem Thema angesehen, aber ich kann meinem CGI-Script keine Codieranweisung # -*- coding: iso-8859-1 -*-mitgeben, weil es dann unter Apache2 nicht mehr ausführbar ist.

Code: Alles auswählen

AddCharset ISO-8859-1  .iso8859-1  .latin1
ist im Apache aktiviert.
Was muss ich anstellen, damit die per POST übergebenen Umlaute richtig interpretiert werden ?

Gruss, Seven
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

Mittwoch 3. Mai 2006, 12:23

snakeseven hat geschrieben:Hi,
ich habe mir einige Threads zu diesem Thema angesehen, aber ich kann meinem CGI-Script keine Codieranweisung # -*- coding: iso-8859-1 -*-mitgeben, weil es dann unter Apache2 nicht mehr ausführbar ist.
Hi Seven!

Dieses Beispiel sollte alles aussagen. Falls doch noch eine Frage auftaucht --> fragen.

Code: Alles auswählen

#!/usr/bin/env python
# -*- coding: iso-8859-1 -*-

print "Content-Type: text/html;charset=iso-8859-1"
print

import cgi
import cgitb; cgitb.enable()
import time

print \
"""<html>
<head>
  <meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1" />
  <title>CGI-Test</title>
</head>
<body>
  <table border="1" cellspacing="0" cellpadding="3">
"""

data = (
    ("Gerold", "Penzö"),
    ("Bernhard", "Winklerß"),
    ("Thomas", "Übermann"),
)
for row in data:
    print "    <tr>"
    for item in row:
        print "      <td>%s</td>" % item
    print "      <td>%s</td>" % time.ctime()
    print "    </tr>"

print \
"""
  </table>
</body>
</html>
"""
lg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

Mittwoch 3. Mai 2006, 12:26

snakeseven hat geschrieben:Was muss ich anstellen, damit die per POST übergebenen Umlaute richtig interpretiert werden?
Hi Seven!

Wenn in allen Seiten (Quelle und Ziel eines Formulars) das Coding angegeben ist, dann sollte es keine Probleme mit den Umlauten geben.

lg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
snakeseven
User
Beiträge: 405
Registriert: Freitag 7. Oktober 2005, 14:37
Wohnort: Berlin
Kontaktdaten:

Mittwoch 3. Mai 2006, 12:46

Hi Gerold,
Die HTML-Seiten enthalten alle ein

Code: Alles auswählen

charset=utf-8"
.
Das Pythonscript habe ich erweitert:

Code: Alles auswählen

import cgitb; cgitb.enable()
print "Content-type: text/html;charset=utf-8"

Code: Alles auswählen

# -*- coding: utf-8 -*-
muss ich weglassen, sonst ist das Script als CGI nicht ausführbar (warum verstehe ich nicht :roll: , es wurde im utf-8 Format abgespeichert).

Es geht leider immer noch nicht.

Gruss, Seven
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

Mittwoch 3. Mai 2006, 13:11

snakeseven hat geschrieben:

Code: Alles auswählen

import cgitb; cgitb.enable()
print "Content-type: text/html;charset=utf-8"

Code: Alles auswählen

# -*- coding: utf-8 -*-
muss ich weglassen, sonst ist das Script als CGI nicht ausführbar (warum verstehe ich nicht :roll: , es wurde im utf-8 Format abgespeichert).
Hi Seven!

1. Vergiss bitte nicht, den Charset auch als Meta-Tag anzugeben:
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">

2. Alle Seiten müssen im gleichen Coding sein. Auch die Seite die nur das Formular enthält. Auch dort muss der Meta-Tag angegeben werden. Du musst dich auch vergewissern, dass die Seite mit dem Formular auch wirklich als utf8-Datei abgespeichert wurde.

3. Wenn alles UTF-8 ist, was der Apache ausliefern soll, dann kannst du zusätzlich in die Konfiguration des Apachen die Zeile

Code: Alles auswählen

AddDefaultCharset utf-8
aufnehmen. Dann sollte aber auch wirklich jede HTML-Datei oder Python-Datei im UTF-8 vorliegen. Muss aber nicht unbedingt sein. Ich glaube der Apache versucht zumindest es auszuliefern.

Versuche raus zu finden, warum

Code: Alles auswählen

# -*- coding: utf-8 -*-
bei dir nicht funktioniert. Das weist eher darauf hin, dass die Datei nicht wirklich als UTF-8 abgespeichert ist. Versuche einfach mal die Datei (mit coding-Tag in der zweiten Zeile) direkt über die Konsole auszuführen. Ohne über den Apachen zu gehen. Gibt es da einen Fehler? --> python dateiname.py

Was zeigt der Befehl "locale" in der Konsole an? Ist das Standard-Encoding wirklich "utf-8"?

lg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
snakeseven
User
Beiträge: 405
Registriert: Freitag 7. Oktober 2005, 14:37
Wohnort: Berlin
Kontaktdaten:

Mittwoch 3. Mai 2006, 16:07

Ne, nützt leider nix.
Habe es erstmal mit einer Seite ausprobiert. Also Seite in SciTE geladen und als utf-8 abgespeichert. Der Metag-Tag mit dem utf-8 Coding war bereits richtig gesetzt. Die Seite enthält die relevanten Listboxen mit den Texteinträgen (einige mit Sonderzeichen/Umlauten).

Dasselbe nochmal mit dem Python-CGI.
Fehlermeldung:

Code: Alles auswählen

Premature end of script headers: bestell1.py
In der Konsole ausgeführt gehts auch nicht.

Code: Alles auswählen

Traceback (most recent call last):
  File "/var/www/vhosts/audioplazza.de/cgi-bin/bestell1.py", line 29, in ?
    gv.name = form["selectName"].value
  File "/usr/lib/python2.4/cgi.py", line 559, in __getitem__
    raise KeyError, key
KeyError: 'selectName'
 
'locale' ergibt das hier:

Code: Alles auswählen

LANG=
LC_CTYPE="POSIX"
LC_NUMERIC="POSIX"
LC_TIME="POSIX"
LC_COLLATE="POSIX"
LC_MONETARY="POSIX"
LC_MESSAGES="POSIX"
LC_PAPER="POSIX"
LC_NAME="POSIX"
LC_ADDRESS="POSIX"
LC_TELEPHONE="POSIX"
LC_MEASUREMENT="POSIX"
LC_IDENTIFICATION="POSIX"
LC_ALL=

Code: Alles auswählen

AddDefaultCharset utf-8
war im Apachen bereits gesetzt.

Ohne die 2.Zeile gehts, aber ohne die Umlaute. Auf dem heimischen Apache läuft alles, nur auf dem VServer nicht !? Das muss an dem liegen, aber ich kenne mich nicht besonders gut mit dem Apachen aus.

Gruss + Danke für deine Mühe !
Seven
Leonidas
Administrator
Beiträge: 16024
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Mittwoch 3. Mai 2006, 20:37

snakeseven hat geschrieben:sonst ist das Script als CGI nicht ausführbar (warum verstehe ich nicht :roll: , es wurde im utf-8 Format abgespeichert).
Scheint so, als könnte dein Apache nicht mit dem BOM umgehen. Merkwürdig.
My god, it's full of CARs! | Leonidasvoice vs Modvoice
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

Mittwoch 3. Mai 2006, 20:59

snakeseven hat geschrieben:Fehlermeldung:

Code: Alles auswählen

Premature end of script headers: bestell1.py
In der Konsole ausgeführt gehts auch nicht.

Code: Alles auswählen

Traceback (most recent call last):
  File "/var/www/vhosts/audioplazza.de/cgi-bin/bestell1.py", line 29, in ?
    gv.name = form["selectName"].value
  File "/usr/lib/python2.4/cgi.py", line 559, in __getitem__
    raise KeyError, key
KeyError: 'selectName'
Hi Seven!

Du brauchst unbedingt diese Zeile:

Code: Alles auswählen

# -*- coding: utf-8 -*-
Und wenn das aus irgendeinem Grund nicht funktioniert, dann musst du raus finden warum es nicht funktioniert.

Ich schlage vor, dass du eine komplett neue Datei erstellst und diese Zeile für Zeile befüllst. Zuerst mal ein minimales CGI-Skript, das überhaupt nicht auf die Formularfelder zugreift. Das testest du dann vorher mal in der Konsole und dann über den Apachen. Wenn das hin haut, dann würde ich Block für Block hinzufügen und immer wieder testen.

Kopiere den Text aber auf keinen Fall direkt. Dann könntest du unabsichtlich wieder ein Sonderzeichen kopieren, das eventuell die Ursache für dein Problem ist.

Kleiner Tipp: Wenn du hier im Forum im "Testforum" einen neuen Beitrag machst und dann auf Vorschau klickst, dann ist dein Skript bereinigt. Du musst es nur wieder von der Vorschau kopieren und in eine frische, leere Textdatei einfügen.

Code: Alles auswählen

# -*- coding: utf-8 -*-
Das muss funktionieren. Erst dann kannst du weiter machen.

Mehr fällt mir dazu nicht ein.

lg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
snakeseven
User
Beiträge: 405
Registriert: Freitag 7. Oktober 2005, 14:37
Wohnort: Berlin
Kontaktdaten:

Montag 8. Mai 2006, 13:23

gerold hat geschrieben:Du brauchst unbedingt diese Zeile:

Code: Alles auswählen

# -*- coding: utf-8 -*-
Ja, habe alles versucht. Alle Scripte mit der Coding-Anweisung versehen, alle Scripte und HTMLs als UTF-8 abgespeichert, alle HTMLs mit dem Coding Meta-Tag versehen. Aber sobald die Scripte als CGI aufgerufen werden, sind sie nicht ausführbar, erst wenn ich die Codingzeile wieder entferne. Werde es jetzt erstmal so machen, daß in den HTML-Seiten zwar Umlaute zu sehen sind, aber übergeben werde ich 'ae,ue' und 'oe'. Dann kann ich wenigstens weitermachen, bis ich den Fehler lokalisiert habe.

Gruss, Seven
BlackJack

Montag 8. Mai 2006, 21:53

Was landet denn im Serverlog wenn Du die Codingzeile drin hast?
snakeseven
User
Beiträge: 405
Registriert: Freitag 7. Oktober 2005, 14:37
Wohnort: Berlin
Kontaktdaten:

Montag 22. Mai 2006, 09:05

Das da:

Code: Alles auswählen

[Sun May 21 22:49:35 2006] [error] [client 127.0.0.1] Premature end of script headers: bestell1.py, referer: http://localhost/order/autohaus.html
[Sun May 21 22:49:36 2006] [error] [client 127.0.0.1] File does not exist: /srv/www/htdocs/favicon.ico
Da kann ich nu' gar nix mit anfangen !??
Gruss, Seven
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

Montag 22. Mai 2006, 09:56

snakeseven hat geschrieben:Das da:

Code: Alles auswählen

[Sun May 21 22:49:35 2006] [error] [client 127.0.0.1] Premature end of script headers: bestell1.py, referer: http://localhost/order/autohaus.html
[Sun May 21 22:49:36 2006] [error] [client 127.0.0.1] File does not exist: /srv/www/htdocs/favicon.ico
Da kann ich nu' gar nix mit anfangen !??
Gruss, Seven
Hi Seven!

Code: Alles auswählen

[Sun May 21 22:49:36 2006] [error] [client 127.0.0.1] File does not exist: /srv/www/htdocs/favicon.ico
Der Browser sieht nur nach, ob es ein Symbol gibt, das mit der URL angezeigt werden kann oder welches bei den Bookmarks als Icon dienen kann. --> Ignorieren.

Code: Alles auswählen

[Sun May 21 22:49:35 2006] [error] [client 127.0.0.1] Premature end of script headers: bestell1.py, referer: http://localhost/order/autohaus.html
Diese Zeile zeigt meist an, dass die Kopfzeile nicht mit "\n" sondern mit "\r\n" abgeschlossen wurde.

Es ist, unter Linux, besonders wichtig, dass die Zeile "#!/usr/bin/env python" nur mit "\n" und nicht mit "\r\n" abgeschlossen wurde. Das gilt auch für die Zeile mit dem Coding (# -*- coding: utf-8 -*-).

Ein Bearbeiten des Skriptes mit "dos2unix", um die Zeilenendzeichen richtig zu setzen, hilft da meist Wunder.

Ob das überhaupt der Grund für den Fehler ist, das findest du mit diesem kleinen Programm heraus:

Code: Alles auswählen

#filename: ord2lines.py
import sys

print "13 = Return"
print "10 = Linefeed"
print 

f = file(sys.argv[1], "r")
for i in range(2):
    print [ ord(ch) for ch in f.readline() ]
f.close()
Übergebe als Kommandozeilenparameter den Namen des zu prüfenden Skriptes:

Code: Alles auswählen

python ord2lines.py mein_cgiskript.py
Das sollte in etwa so aussehen:

Code: Alles auswählen

gerold@gpw ~ $ python ord2lines.py xxxx.py
13 = Return
10 = Linefeed

[35, 33, 47, 117, 115, 114, 47, 98, 105, 110, 47, 101, 110, 118, 32, 112, 121, 116, 104, 111, 110, 10]
[35, 32, 45, 42, 45, 32, 99, 111, 100, 105, 110, 103, 58, 32, 117, 116, 102, 45, 56, 32, 45, 42, 45, 10]
gerold@gpw ~ $
Wie man sieht, enden die ersten beiden Zeilen des untersuchten Skriptes mit "10". -- Das ist OK. Wenn aber die Zeilen mit "13, 10" enden, dann läuft etwas falsch.

lg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
snakeseven
User
Beiträge: 405
Registriert: Freitag 7. Oktober 2005, 14:37
Wohnort: Berlin
Kontaktdaten:

Montag 22. Mai 2006, 10:35

Hi Gerold,
danke für die ausführliche Antwort !

Das Linefeedproblem hatte ich ja schon zu Beginn meiner ersten CGI-Versuche, ist aber längst gelöst. Ich programmiere mittlerweile fast ausschließlich auf Linux und habe auch SciTE auf die entsprechenden Linefeeds eingestellt. Ich habe aber mal den Gegentest mit # -*- coding: iso-8859-1 -*- gemacht, also auch den entsprechenden Meta-Tag in den HTML-Code eingefügt und das funktioniert. Nur mit UTF-8 gehts nicht !?
Mache jetzt erstmal mit ISO-8859-1 weiter.

Gruss, Seven

P.S. Habe mein Script durch dein Testprogramm geschickt. Alles so wies sein soll.

Code: Alles auswählen

[35, 33, 47, 117, 115, 114, 47, 98, 105, 110, 47, 101, 110, 118, 32, 112, 121, 116, 104, 111, 110, 10]
[35, 32, 45, 42, 45, 32, 99, 111, 100, 105, 110, 103, 58, 32, 105, 115, 111, 45, 56, 56, 53, 57, 45, 49, 32, 45, 42, 45, 10]
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

Montag 22. Mai 2006, 11:24

Hi Seven!
snakeseven hat geschrieben:Das Linefeedproblem hatte ich ja schon zu Beginn meiner ersten CGI-Versuche, ist aber längst gelöst. Ich programmiere mittlerweile fast ausschließlich auf Linux und habe auch SciTE auf die entsprechenden Linefeeds eingestellt.
Nur mal um wirklich sicher zu gehen:
http://www.python-forum.de/viewtopic.php?p=37008#37008
snakeseven hat geschrieben: Ich habe aber mal den Gegentest mit # -*- coding: iso-8859-1 -*- gemacht, also auch den entsprechenden Meta-Tag in den HTML-Code eingefügt und das funktioniert. Nur mit UTF-8 gehts nicht!?
Wenn du statt "iso-8859-1" "utf-8" als Coding in der zweiten Zeile angibst, änderst du dann das Coding der Datei auch oder schreibst du nur "utf-8" rein?
Die ganze Sache kann nur dann funktionieren, wenn du die Datei als "UTF-8"-Datei speicherst **und** das Coding angibst.

Vielleicht kommst du mit diesem Skript weiter. Es wandelt eine Datei, die im Standard-Coding des Systems gespeichert wurde nach UTF-8 um.
http://www.python-forum.de/topic-4748.html

lg
Gerold
:-)

PS: Ich glaube, dass Scite nicht automatisch erkennt in welchem Coding eine Datei abgespeichert wurde.
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Benutzeravatar
jens
Moderator
Beiträge: 8483
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Montag 22. Mai 2006, 11:28

gerold hat geschrieben:Vielleicht kommst du mit diesem Skript weiter. Es wandelt eine Datei, die im Standard-Coding des Systems gespeichert wurde nach UTF-8 um.
http://www.python-forum.de/topic-4748.html
Mit SciTE kann man unter "File / Encoding" das erledigen. Ich nutzte dazu immer "UTF-8 Cookie" das ist IMHO ohne BOM...
gerold hat geschrieben:PS: Ich glaube, dass Scite nicht automatisch erkennt in welchem Coding eine Datei abgespeichert wurde.
Unter Windows hab ich auch öfters mal Probleme, da werden Umlaute mal kaputt gemacht ;( Allerdings ist das für Apache egal. Nur: Apache kann wirklich nicht mit einem BOM umgehen, IMHO!

Das steht aber alles schon unter: [wiki]Web-Skripte zum laufen bringen[/wiki]

Sollte da was fehlen, bitte eintragen!

CMS in Python: http://www.pylucid.org
GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Antworten