Flask: flash() javscript upload html5 problem

Django, Flask, Bottle, WSGI, CGI…
Antworten
taake
User
Beiträge: 125
Registriert: Donnerstag 14. Oktober 2010, 08:49

Hallo zusammen,
ich hab hier gerade ein Problem wo ich nicht wirklich weiterkomme.
Und zwar will ich meiner website nen Fortschrittsbalken beim upload gönnen.

Problem das meine flash() aufrufe nun nicht mehr gehen, scheinbar liegt es daran das das mit dem reload der site nicht mehr wie vorgesehen läuft.
lt debugger ruft er die site schon neu wieder auf, allerdings kommen die flash() nicht.
Was etwas ungünstig ist, abgesehen davon klappt alles.


Meine Upload Funktion sieht zur Zeit so aus

Code: Alles auswählen

@app.route('/upload/', methods=['GET', 'POST'])
def file_upload():
    print request.method
#    flash('Upload Form!')
    if request.method == 'POST':
#        print request.files
        file = request.files['datei']
        if file and allowed_file(file.filename):
            filename = secure_filename(file.filename)
            file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
            flash('Danke fuer ihren Upload')
            return redirect(url_for('file_upload'))
        else:
            print 'error wrong format'
            flash('Fehler, moeglicherweise ist das Dateiformat nicht erlaubt')
    return render_template('upload_html5.html', support=app.config['ALLOWED_EXTENSIONS'], title='Upload your stuff')
Den Fileupload hab ich nach folgendem Rezept gemacht:

Code: Alles auswählen

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>File-Upload mit Fortschrittanzeige</title>
</head>
 
<body>
<script type="text/javascript">
 
function fileChange()
{
    //FileList Objekt aus dem Input Element mit der ID "fileA"
    var fileList = document.getElementById("fileA").files;
 
    //File Objekt (erstes Element der FileList)
    var file = fileList[0];
 
    //File Objekt nicht vorhanden = keine Datei ausgewählt oder vom Browser nicht unterstützt
    if(!file)
        return;
 
    document.getElementById("fileName").innerHTML = 'Dateiname: ' + file.name;
    document.getElementById("fileSize").innerHTML = 'Dateigröße: ' + file.size + ' B';
    document.getElementById("fileType").innerHTML = 'Dateitype: ' + file.type;
    document.getElementById("progress").value = 0;
    document.getElementById("prozent").innerHTML = "0%";
}
 
var client = null;
 
function uploadFile()
{
    //Wieder unser File Objekt
    var file = document.getElementById("fileA").files[0];
    //FormData Objekt erzeugen
    var formData = new FormData();
    //XMLHttpRequest Objekt erzeugen
       client = new XMLHttpRequest();
 
    var prog = document.getElementById("progress");
 
    if(!file)
        return;
 
    prog.value = 0;
    prog.max = 100;
 
    //Fügt dem formData Objekt unser File Objekt hinzu
    formData.append("datei", file);
 
    client.onerror = function(e) {
        alert("onError");
    };
 
    client.onload = function(e) {
        document.getElementById("prozent").innerHTML = "100%";
        prog.value = prog.max;
    };
 
    client.upload.onprogress = function(e) {
        var p = Math.round(100 / e.total * e.loaded);
        document.getElementById("progress").value = p;            
        document.getElementById("prozent").innerHTML = p + "%";
    };
 
    client.onabort = function(e) {
        alert("Upload abgebrochen");
    };
 
    client.open("POST", "upload.php");
    client.send(formData);
}
 
function uploadAbort() {
    if(client instanceof XMLHttpRequest)
        client.abort();
}
</script>
 
<form action="" method="post" enctype="multipart/form-data">
    <input name="file" type="file" id="fileA" onchange="fileChange();"/>
    <input name="upload" value="Upload" type="button" onclick="uploadFile();" />
    <input name="abort" value="Abbrechen" type="button" onclick="uploadAbort();" />
</form>
<div>
    <div id="fileName"></div>
    <div id="fileSize"></div>
    <div id="fileType"></div>
    <progress id="progress" style="margin-top:10px"></progress> <span id="prozent"></span>
</div>
 
</body>
</html>
Quelle: http://www.it-gecko.de/html5-file-uploa ... ment-71302

Natürlich hab das obere an meine Wünsche angepasst, wie gesagt läuft auch alles. die struktur die flash() benötigt ist auch da, vorher lief es ja auch, da war es halt nur nen simples form das die datei übergeben hat, ohne Fortschrittsbalken.

Hab das ganze auch um das hier erweitert.

Code: Alles auswählen

    client.onloadend = function(e) {
//       location.reload()
       //alert("Upload beendet")
    };
Funktioniert auch wird am Ende des uploades getriggert, allerdings trotz reload bleibt das flash() event aus.

Leider kenn ich mich mit javascript so gut wie gar nicht aus.
Hoffe es ist einigermaßen klar was ich meine und das irgendwer nen Tipp für mich hat wie man dem ganzen begegnen kann.
taake
User
Beiträge: 125
Registriert: Donnerstag 14. Oktober 2010, 08:49

Da der Edit Button dem neuen Layout wohl zum Opfer gefallen ist, halt als neuer Beitrag ...

EDIT:
Also muss auch nicht flash() basiert sein, wäre schon nice weil ich dann wüsste wie man das Problem löst.
Allerdings geht es primär halt darum nen Feedback geben zu können.

Und by the way, gibt es eigentlich eine Möglichkeit die Dateiendung zu überprüfen bevor die Datei vollständig hochgeladen ist?
also in der set() von app.config['ALLOWED_EXTENSIONS'] nachschauen bevor die Datei hochgeladen wird.


Edit2: Interessant, der Editbutton ist bei diesem Beitrag jetzt vorhanden, nur so als Randbemerkung.
BlackJack

@taake: Bearbeiten von Beiträgen ist zeitlich begrenzt und auch nicht mehr möglich wenn auf den Beitrag geantwortet wurde. War leider nötig weil es Leute gibt die exzessiv Ihre Beiträge nachträglich überarbeiten, so dass die Diskussion am Ende nicht mehr nachvollziehbar ist, beziehungsweise der Inhalt verzerrt wird.
taake
User
Beiträge: 125
Registriert: Donnerstag 14. Oktober 2010, 08:49

Also hab es jetzt zum laufen bekommen, allerdings ist das eher so "dreckiger Hack"
also offen ist das Thema für mich immer noch, Kommentare, Verbesserungen usw. sind definitiv willkommen.

In der Datei upload_html5.html, in dem javascript (siehe initpost)
muss folgendes erweitert werden:

Code: Alles auswählen

client.onloadend = function(e) {
        location.reload()
};
Also den Reload der Site sobald der upload fertig ist.

Auf der flask seite muss man die return redirect(url_for()) um ein html status code erweitern, damit aus:

127.0.0.1 - - [25/Feb/2016 09:30:04] "POST /upload/ HTTP/1.1" 302 -
ein
127.0.0.1 - - [25/Feb/2016 09:30:24] "POST /upload/ HTTP/1.1" 200 -
wird
Dann laufen die flash() wieder, wie gesagt dreckiger Hack, wenn jemand da weiß wie man das besser lösen kann, immer her damit.

Das ganze sieht wie folgt aus:

Code: Alles auswählen

@app.route('/upload/', methods=['GET', 'POST'])
def file_upload():
    if request.method == 'POST':
        file = request.files['datei']
        if file and allowed_file(file.filename):
            filename = secure_filename(file.filename)
            file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
            flash('Danke fuer ihren Upload')
            return redirect(url_for('file_upload'),200)
        else:
            flash('Fehler, moeglicherweise ist das Dateiformat nicht erlaubt')
            return redirect(url_for('file_upload'),200)
    return render_template('upload_html5.html', support=app.config['ALLOWED_EXTENSIONS'], title='Upload your stuff')
Bleibt noch die Frage mit dem dem checken der erlaubenten extensions offen, kann man wohl auch in dem javascript machen, aber halt javascript..., mir wäre da was auf der flask Seite lieber, auch wenn ich da gerade keine Idee habe wie genau.

Edit:
Ist es möglich das es daran liegt wie das POST abgeschickt wird, im Orginal ist es:
client.open("POST", "upload.php");
client.send(formData);

Ich habe das ganze in client.open("POST", "."); abgeändert damit es halt an meine Upload funktion als POST geht, also ist nur ne Idee, kA ob es daran liegen kann, kann es aber nicht vollkommen ausschließen, daher wollte ich Euch die Info nicht vorenthalten.
Antworten