Fortschritt beim Hochladen von jQuery und Hochladen von AJAX-Dateien

72

Es scheint, als hätte ich mein Problem nicht klar kommuniziert. Ich muss eine Datei senden (mit AJAX) und den Upload-Fortschritt der Datei mit dem Nginx HttpUploadProgressModule abrufen . Ich brauche eine gute Lösung für dieses Problem. Ich habe es mit dem Plugin jquery.uploadprogress versucht, aber ich muss viel davon neu schreiben, damit es in allen Browsern funktioniert und die Datei mit AJAX gesendet wird.

Ich brauche dazu nur den Code, der in allen gängigen Browsern (Chrome, Safari, FireFox und IE) funktioniert. Es wäre sogar noch besser, wenn ich eine Lösung finden könnte, die mehrere Datei-Uploads unterstützt.

Ich verwende das Plugin jquery.uploadprogress , um den Upload-Fortschritt einer Datei aus dem NginxHttpUploadProgressModule abzurufen. Dies befindet sich in einem Iframe für eine Facebook-Anwendung. Es funktioniert in Firefox, aber es schlägt in Chrome / Safari fehl.

Wenn ich die Konsole öffne, bekomme ich das.

Uncaught ReferenceError: progressFrame is not defined
jquery.uploadprogress.js:80

Irgendeine Idee, wie ich das beheben würde?

Ich möchte die Datei auch mit AJAX senden, wenn sie fertig ist. Wie würde ich das umsetzen?

EDIT:
Ich brauche das bald und es ist wichtig, also werde ich ein 100-Punkte-Kopfgeld auf diese Frage setzen. Die erste Person, die darauf antwortet, erhält die 100 Punkte.

EDIT 2:
Jake33 hat mir geholfen, das erste Problem zu lösen. Die erste Person, die eine Antwort zum Senden der Datei mit Ajax hinterlässt, erhält die 100 Punkte.

Conceited Code
quelle
2
Ich sehe, dass es Browser-Sniffing verwendet, um Safari zu erkennen (Browser-Sniffing wird normalerweise verpönt), daher wird progressFrame nur mit Safari / Chrome verwendet (ich weiß nicht warum). Der Teil, in dem der Fehler auftritt, scheint der zu sein, in dem das Skript versucht, auf progressFrame zu verweisen, indem es im globalen Bereich nach seinem Namen sucht, anstatt eine Funktion wie zu verwenden document.getElementsByName.
Jhartz
1
Ich bin mir nicht sicher, was Sie unter "Senden mit AJAX nach Abschluss" verstehen. Stellt der Fortschrittsbalken nicht den Fortschritt der Einreichung dar? Bedeutet das nicht, dass es bereits gesendet wird, sobald es abgeschlossen ist? Meinen Sie damit, dass die ursprüngliche Formularübermittlung von AJAX gesteuert werden soll, damit nachher keine Seitenaktualisierung erfolgt?
Slifty
Ja. Ja, aber es verhält sich wie eine Formularübermittlung. Das ist genau das, was ich will.
Conceited Code
Wenn die Frage, wie Sie Daten mit einem HTTP-POST über XMLHttpRequest mit jQuery senden, dann gibt es jQuery.post
karlcow
1
Funktionieren die folgenden Antworten für Sie? Wenn nicht, können Sie die Antworten kommentieren. Ich bin aufgrund all der Änderungen etwas verwirrt und möchte versuchen, Ihr Problem zu lösen. Vielen Dank. Übrigens habe ich einen Link für das Plugin zum Hochladen mehrerer Dateien von JQuery eingefügt.
jmort253

Antworten:

214

Das Hochladen von Dateien ist heutzutage mit AJAX tatsächlich möglich. Ja, AJAX, nicht irgendwelche beschissenen AJAX-Möchtegern wie swf oder java.

Dieses Beispiel könnte Ihnen helfen: https://webblocks.nl/tests/ajax/file-drag-drop.html

(Es enthält auch die Drag & Drop-Oberfläche, die jedoch leicht ignoriert werden kann.)

Grundsätzlich kommt es darauf an:

<input id="files" type="file" />

<script>
document.getElementById('files').addEventListener('change', function(e) {
    var file = this.files[0];
    var xhr = new XMLHttpRequest();
    (xhr.upload || xhr).addEventListener('progress', function(e) {
        var done = e.position || e.loaded
        var total = e.totalSize || e.total;
        console.log('xhr progress: ' + Math.round(done/total*100) + '%');
    });
    xhr.addEventListener('load', function(e) {
        console.log('xhr upload complete', e, this.responseText);
    });
    xhr.open('post', '/URL-HERE', true);
    xhr.send(file);
});
</script>

(Demo: http://jsfiddle.net/rudiedirkx/jzxmro8r/ )

Im Grunde kommt es also darauf an =)

xhr.send(file);

Wo fileist der Typ Blob: http://www.w3.org/TR/FileAPI/

Eine andere (bessere IMO) Möglichkeit ist die Verwendung FormData. Auf diese Weise können Sie 1) eine Datei wie in einem Formular benennen und 2) andere Inhalte (auch Dateien) wie in einem Formular senden.

var fd = new FormData;
fd.append('photo1', file);
fd.append('photo2', file2);
fd.append('other_data', 'foo bar');
xhr.send(fd);

FormData macht den Servercode sauberer und abwärtskompatibler (da die Anforderung jetzt genau das gleiche Format wie normale Formulare hat).

Alles ist nicht experimentell, aber sehr modern. Chrome 8+ und Firefox 4+ wissen, was zu tun ist, aber ich kenne keine anderen.

So habe ich die Anfrage (1 Bild pro Anfrage) in PHP behandelt:

if ( isset($_FILES['file']) ) {
    $filename = basename($_FILES['file']['name']);
    $error = true;

    // Only upload if on my home win dev machine
    if ( isset($_SERVER['WINDIR']) ) {
        $path = 'uploads/'.$filename;
        $error = !move_uploaded_file($_FILES['file']['tmp_name'], $path);
    }

    $rsp = array(
        'error' => $error, // Used in JS
        'filename' => $filename,
        'filepath' => '/tests/uploads/' . $filename, // Web accessible
    );
    echo json_encode($rsp);
    exit;
}
Rudie
quelle
12
IE 9 weiß das nicht. :(
Rocky
27
Dies ist eine Funktion, die nur in XMLHttpRequest2 verfügbar ist. Eine vollständige Kompatibilitätsliste finden Sie unter caniuse.com/xhr2
YS.
@ Rudie Hast du den Link zum Tutorial hotblocks.nl? nicht nur die Demo Danke in adv
vzhen
1
@NeilMartin Ich habe am Ende der Antwort PHP-Beispielcode hinzugefügt. Natürlich möchten Sie etwas anderes damit machen.
Rudie
1
Ich bin nicht sicher, ob ich verstehe, wie das funktioniert? Ich wäre großartig, wenn Sie irgendwo ein vollständiges Arbeitsbeispiel und eine Demo online erstellen könnten. Oder vielleicht eine Anleitung, wie es funktioniert und was die Dinge tun?
Drooh
17

Hier sind einige Optionen für die Verwendung von AJAX zum Hochladen von Dateien:

UPDATE: Hier ist ein JQuery-Plug-In zum Hochladen mehrerer Dateien .

jmort253
quelle
2
Ich habe plUpload in mehreren Projekten mit Erfolg verwendet (Multi-Datei-Upload mit Fortschritt, unterstützt Flash / Html5 / Silverlight usw.)
Guillaume86
1
AjaxFileUpload ist ein Miststück. Es ist nicht kompatibel mit einer neueren Version von jquery als 1.5. Auch der Code ist böse hässlich.
Adam
1
@Adam - Gut zu wissen. Ich denke, in einem Jahr hat sich viel geändert. Unsere Haare werden etwas grauer und JavaScript-Bibliotheken funktionieren nicht mehr mit neueren Softwareversionen ...
jmort253
1
Um @Adam zu erweitern, bricht AjaxFileUpload am ie9 +
0plus1
1
@RanaMuhammadUsman - Schauen Sie jetzt noch einmal. Ich glaube, ich habe den Speicherort der verschobenen Plugins gefunden. Hoffe das hilft.
jmort253