web-dev-qa-db-fra.com

Progression du téléchargement jQuery et AJAX)

Il semble que je n’ai pas clairement communiqué mon problème. Je dois envoyer un fichier (avec AJAX) et obtenir la progression du téléchargement du fichier à l'aide de Nginx HttpUploadProgressModule . J'ai besoin d'une bonne solution à ce problème. J'ai essayé avec le plugin jquery.uploadprogress, mais je me retrouve à devoir réécrire une grande partie de celui-ci pour qu'il fonctionne dans tous les navigateurs et pour envoyer le fichier à l'aide d'AJAX.

Tout ce dont j'ai besoin, c'est du code pour le faire et cela doit fonctionner dans tous les principaux navigateurs (Chrome, Safari, FireFox et IE). Ce serait encore mieux si je pouvais obtenir une solution capable de gérer plusieurs téléchargements de fichiers.

J'utilise le plugin jquery.uploadprogress pour obtenir la progression du téléchargement d'un fichier à partir du NginxHttpUploadProgressModule. Ceci est à l'intérieur d'un iframe pour une application facebook. Cela fonctionne sous firefox, mais échoue sous chrome/safari.

Lorsque j'ouvre la console, je reçois ceci.

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

Une idée de comment je réglerais ça?

Je voudrais aussi envoyer le fichier en utilisant AJAX quand il sera terminé. Comment pourrais-je implémenter cela?

EDIT:
J'ai besoin de ça bientôt et c'est important, je vais donc mettre une prime de 100 points sur cette question. La première personne à y répondre recevra les 100 points.

EDIT 2:
Jake33 m'a aidé à résoudre le premier problème. La première personne à laisser une réponse indiquant comment envoyer le fichier avec ajax recevra également les 100 points.

69
Conceited Code

Le téléchargement de fichiers est en fait possible avec AJAX ces jours-ci. Oui, AJAX, pas un peu merdique AJAX Wannabes comme swf ou Java.

Cet exemple pourrait vous aider: https://webblocks.nl/tests/ajax/file-drag-drop.html

(Il inclut également l'interface glisser/déposer mais c'est facilement ignoré.)

En gros, voici ce qu’il en résulte:

<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>

(démo: http://jsfiddle.net/rudiedirkx/jzxmro8r/ )

Donc, fondamentalement, cela revient à ceci =)

xhr.send(file);

file est typeof Blob: http://www.w3.org/TR/FileAPI/

Une autre façon (meilleure OMI) consiste à utiliser FormData. Cela vous permet 1) de nommer un fichier, comme dans un formulaire, et 2) d’envoyer d’autres éléments (également des fichiers), comme dans un formulaire.

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

FormData rend le code serveur plus propre et plus compatible avec les versions antérieures (puisque la requête a maintenant exactement le même format que les formulaires normaux).

Tout cela n’est pas expérimental, mais très moderne. Chrome 8+ et Firefox 4+ savent quoi faire, mais je ne connais pas d’autres.

Voici comment j'ai traité la demande (1 image par demande) en PHP:

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;
}
203
Rudie

Voici quelques options pour utiliser AJAX pour télécharger des fichiers:

UPDATE: Voici un plug-in JQuery pour Téléchargement de plusieurs fichiers .

16
jmort253