JQuery und Python mittels CGI-BIN gibt immer \n zurück

Django, Flask, Bottle, WSGI, CGI…
Antworten
AngelusNoctis
User
Beiträge: 92
Registriert: Sonntag 16. Dezember 2007, 20:03

Hi

Vorab ich weiss fastcgi oder cgi-bin ist nicht ideal, aber mein Hoster bietet kein Django o.ö. an, also nehm ich dies.

Nun zu meiner Frage.

Mir ist aufgefallen das bei einer $._post Anfrage von JQuery ständig ein "string\n" bzw "\n" zurückgegeben wird, obwohl dieser nirgends angegeben wird im python script.

Kann mir jemand erklären woher der kommt?

z.B. steck im "response = True" am ende ein "True\n" drin bei der Rückgabe in data anstelle von "True".

PS. Erklärt auch wieso ich "match" nutze ^^

Code: Alles auswählen

    $('#login_form').submit(function(event) {
        $('#warning').html('');
        event.preventDefault();
        $.post('cgi-bin/login.py', $(this).serialize(), function(data) {
            if (data.match(/True/)) {
                window.location="http://foo.bar.ch/chat.html";
            } else {
                $('#warning').html(data);
            };
        });
    });

Code: Alles auswählen

               response = True
            else:
                response = 'Benutzername oder Passwort falsch!'
        else:
            response = 'Benutzername oder Passwort falsch!'
    else:
        response = 'Kein Benutzername angegeben.'

if response:
    print "Content-Type: text/html; charset=utf-8"
    print
    print response
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Weil print am Ende immer ein Newline schreibt. Wenn du das umgehen möchtest, dann verwende einfach

Code: Alles auswählen

print response,
Das Leben ist wie ein Tennisball.
AngelusNoctis
User
Beiträge: 92
Registriert: Sonntag 16. Dezember 2007, 20:03

EyDu hat geschrieben:Weil print am Ende immer ein Newline schreibt. Wenn du das umgehen möchtest, dann verwende einfach

Code: Alles auswählen

print response,
Moin moin

Auch mit dem "," am Ende bekomme ich laut Firebug "True\n" zurück und nicht "True" :(


Mit sys.stdout.write() gehts ja oder bei Python 3 aber nur Python 2.7 auf dem Server (kein Root Server) und stdout.write nutzen finde ich doof :(
Sirius3
User
Beiträge: 17747
Registriert: Sonntag 21. Oktober 2012, 17:20

@AngelusNoctis: wenn Du Daten an Javascript übermitteln willst, nimm doch ein passendes Datenformat, JSON, und erfinde nichts eigenes.
AngelusNoctis
User
Beiträge: 92
Registriert: Sonntag 16. Dezember 2007, 20:03

Sirius3 hat geschrieben:@AngelusNoctis: wenn Du Daten an Javascript übermitteln willst, nimm doch ein passendes Datenformat, JSON, und erfinde nichts eigenes.
Naja, was daran erfinden ist weiss ich nicht.

Die print Anweisung wird so vorgeschlagen in der offiziellen Dokumentation von Python bei der Sektion cgi-bin.

Und das $.post() Text, HTML, XML und json entgegennimmt ist auch in der jquery Doku drin.

Es hatte mich einfach interessiert bevor ich noch ein Modul lade und die eh schon schlechte performance von cgi-bin nochmals verschlechterte.

Trotzdem danke.
Sirius3
User
Beiträge: 17747
Registriert: Sonntag 21. Oktober 2012, 17:20

AngelusNoctis hat geschrieben:Die print Anweisung wird so vorgeschlagen in der offiziellen Dokumentation von Python bei der Sektion cgi-bin.
Ich habe nirgends in der Dokumentation gelesen, dass man verschiedene Datentypen ohne Kennzeichnung mischen soll. Du überträgst ja gerade keinen Text, und verschiedene Datentypen lassen sich am einfachsten per JSON kodieren.
BlackJack

@AngelusNoctis: Du erfindest ein „plain text” 'True' dem Du eine Bedeutung gibst. Statt zum Beispiel JSON zu verwenden wo es ein 'true' gibt, dem ein Standard eine Bedeutung gibt der in dem Bereich in dem Du Dein 'True' verwendest auch noch oft genutzt wird. Und dem JSON-Parser im Browser wäre dann auch noch egal ob da ein Zeilenende steht oder nicht und der liefert Dir den JavaScript-Wert `true`:

Code: Alles auswählen

> $.parseJSON('true')
true
> $.parseJSON('true\n')
true
Ausserdem kann man mehr als nur Wahr/Falsch zurückgeben, zum Beispiel auch einen Grund oder Informationen über eventuell auf Serverseite aufgetretene Ausnahmen.
AngelusNoctis
User
Beiträge: 92
Registriert: Sonntag 16. Dezember 2007, 20:03

Sirius3 hat geschrieben:
AngelusNoctis hat geschrieben:Die print Anweisung wird so vorgeschlagen in der offiziellen Dokumentation von Python bei der Sektion cgi-bin.
Ich habe nirgends in der Dokumentation gelesen, dass man verschiedene Datentypen ohne Kennzeichnung mischen soll. Du überträgst ja gerade keinen Text, und verschiedene Datentypen lassen sich am einfachsten per JSON kodieren.
Das True wird ja zu nem normalen String, also ist es kein "Mischen".

typeof data --> string

Ob ich nun if (data === true) oder if (data === 'True') mach wäre mir in dem Fall sogar egal.

Es hat mich nur gewurmt woher dieses verflixte '\n' herkam. Thats it.

In dem Falle fand ich es auch doof extra JSON zu importieren nur wegen einem einzigen True.

Bei Listen, Dic's, None etc nehme ich dann gerne JSON

Trotzdem danke :)
AngelusNoctis
User
Beiträge: 92
Registriert: Sonntag 16. Dezember 2007, 20:03

BlackJack hat geschrieben:@AngelusNoctis: Du erfindest ein „plain text” 'True' dem Du eine Bedeutung gibst. Statt zum Beispiel JSON zu verwenden wo es ein 'true' gibt, dem ein Standard eine Bedeutung gibt der in dem Bereich in dem Du Dein 'True' verwendest auch noch oft genutzt wird. Und dem JSON-Parser im Browser wäre dann auch noch egal ob da ein Zeilenende steht oder nicht und der liefert Dir den JavaScript-Wert `true`:

Code: Alles auswählen

> $.parseJSON('true')
true
> $.parseJSON('true\n')
true
Ausserdem kann man mehr als nur Wahr/Falsch zurückgeben, zum Beispiel auch einen Grund oder Informationen über eventuell auf Serverseite aufgetretene Ausnahmen.
Ja, weil Response bei nem Misserfolg nen String zurückgibt.

Und ich wie schon vorhin gesagt ist egal ist ob nun if (data === true) oder if (data === 'True') und extra JSON importieren wegen einem einzigen Boolean fand ich OP.

Zu JSON greif ich erst wenn ich Listen, Dics, Int etc übergebe oder öfters True/False/None.

Mich hatte nur interessiert woher das \n stammte.

Trotzdem danke :)




PS. Wenn "True" zurückgegeben wird gibt es keine Ausnahme, für alle anderen Fälle hab ich ja die anderen Else mit den Fehlermeldungen :)
Sirius3
User
Beiträge: 17747
Registriert: Sonntag 21. Oktober 2012, 17:20

@AngelusNoctis: Du schreibst einen eigenen, fehleranfälligen Parser in Javascript. Du benutzt magische Werte, an die Du Dich immer erinnern mußt, wenn Du Dein Programm in einigen Jahren erweitern willst. Du hast zusätzlichen Testaufwand, weil Du Dein »Protokoll« extra testen mußt, statt sich auf die Tests einer fertigen Bibliothek zu verlassen.
Und das alles nur, weil Dir das irgendwie zu umständlich vorkommt. Bequemlichkeit rächt sich irgendwann.
BlackJack

@AngelusNoctis: Ich verstehe immer noch nicht was Dein Problem mit einer JSON-Lösung ist und warum Du Dich so stur dagegen wehrst. Beim CGI-Skript änderst Du ein grosses 'T' in ein kleines 't', also ``print 'true'`` statt ``print 'True'`` und auf JavaScript-Seite kommt beim ``$.post()``-Aufruf noch ein zusätzliches Argument mit dem Wert 'json' hinten dran und schon wird ein standardisierter Wert übertragen. Diese beiden minimalen Änderungen erscheinen Dir zu übertrieben? Ernsthaft?
BlackJack

@AngelusNoctis: Und Du mischst doch verschiedene Typen. Dass das auf der Leitung alles zu Zeichenketten/Byteketten werden *muss* ändert ja nichts daran das True eine andere Bedeutung, und im Python-Skript auch noch einen anderen Typ hat, als alle anderen Antworten die auf die Anfrage gesendet werden können. Sonst könnte man mit der Argumentation auch behaupten es wäre grundsätzlich gar nicht möglich verschiedene Typen über Sockets zu übertragen weil dort immer alles nur eine Folge von Bytewerten ist. Das gleiche gilt dann auch für Dateien auf der Festplatte.

Das mit der Zeit um das JSON-Modul zu importieren und eine Datenstruktur in JSON zu serialisieren ist IMHO auch kein Argument. Gerade weil CGI ”so langsam” ist, dürfte diese zusätzliche Zeit einen verschwindend geringen Anteil ausmachen. Ich würde sogar statt CGI trotzdem WSGI und ein Mikrorahmenwerk verwenden, denn WSGI kann man auch über CGI anbinden. Ist zwar nicht ideal, geht aber, und man hat schon eine WSGI-Lösung die auch mit FastCGI oder anderen Technologien geht, bei denen nicht immer alles bei jeder Anfrage neu geladen werden muss.
Antworten