AJAX/PHP d'upload avec barre de progression pour les gros fichiers
J'ai essayé de créer un non-flash télécharger panneau qui montre également une barre de progression.
Sur notre serveur, nous avons PHP 5.3 (impossible de mettre à niveau à 5,4 pour l'instant, la nouvelle progression du chargement de la fonctionnalité ne peut pas être utilisé => http://php.net/manual/en/session.upload-progress.php).
Nous ne pouvons pas utiliser des solutions à base de mémoire flash, extensions ou similaire.
Donc j'ai essayé d'utiliser un XMLHttpRequest combiné avec l'AJAX.
Le problème ici c'est que j'ai seulement réalisé des succès partiels.
J'ai réussi à télécharger et enregistrer sur le serveur un fichier d'environ 380 MO, toutefois, lorsque vous essayez avec un fichier de plus grande taille comme 4 GO, il ne sera pas enregistré sur le serveur (si je vérifie avec Firebug, à un moment donné, il va dire "POST abandonnée").
Une autre chose étrange est que, avec le même fichier de la xhr.le téléchargement.chargé commence avec la même dimension de xhr.le téléchargement.total et commence à compter à partir de là.
Personne ne sait comment résoudre ce problème ou a une solution alternative?
Le code du client est:
<script type="application/javascript" src="jquery.js"></script>
<script type="application/javascript">
function uploadToServer()
{
fileField = document.getElementById("uploadedFile");
var fileToUpload = fileField.files[0];
var xhr = new XMLHttpRequest();
var uploadStatus = xhr.upload;
uploadStatus.addEventListener("progress", function (ev) {
if (ev.lengthComputable) {
$("#uploadPercentage").html((ev.loaded / ev.total) * 100 + "%");
}
}, false);
uploadStatus.addEventListener("error", function (ev) {$("#error").html(ev)}, false);
uploadStatus.addEventListener("load", function (ev) {$("#error").html("APPOSTO!")}, false);
xhr.open(
"POST",
"serverUpload.php",
true
);
xhr.setRequestHeader("Cache-Control", "no-cache");
xhr.setRequestHeader("Content-Type", "multipart/form-data");
xhr.setRequestHeader("X-File-Name", fileToUpload.fileName);
xhr.setRequestHeader("X-File-Size", fileToUpload.fileSize);
xhr.setRequestHeader("X-File-Type", fileToUpload.type);
//xhr.setRequestHeader("Content-Type", "application/octet-stream");
xhr.send(fileToUpload);
}
$(function(){
$("#uploadButton").click(uploadToServer);
});
</script>
Partie HTML:
<form action="" name="uploadForm" method="post" enctype="multipart/form-data">
<input id="uploadedFile" name="fileField" type="file" multiple />
<input id="uploadButton" type="button" value="Upload!">
</form>
<div id="uploadPercentage"></div>
<div id="error"></div>
Côté serveur code:
<?php
$path = "./";
$filename = $_SERVER['HTTP_X_FILE_NAME'];
$filesize = $_SERVER['CONTENT_LENGTH'];
$file = "log.txt";
$fo= fopen($file, "w");
fwrite($fo, $path . PHP_EOL);
fwrite($fo, $filename . PHP_EOL);
fwrite($fo, $filesize . PHP_EOL);
fwrite($fo, $path . $filename . PHP_EOL);
file_put_contents($path . $filename,
file_get_contents('php://input')
);
?>
J'ai déjà vérifié ces et tout semble bien fonctionner.
Cela ressemble à une blague, mais parfois, les gens font des choses stupides, donc je vous la pose quand même : "Êtes-vous en utilisant comme système de fichiers FAT32?"
Avez-vous résoudre le problème déjà? Si oui, pourriez-vous s'il vous plaît partagez votre solution? Si ce n'est pas que sur le fractionnement du fichier en petits morceaux avec du jQuery blob fonction par exemple?
OriginalL'auteur DiG | 2012-04-20
Vous devez vous connecter pour publier un commentaire.
Il y a des limites associées avec le serveur web ne peut pas être changé par PHP. Exemple, leur est un défaut max post taille de la demande de 30MO dans IIS...il y a aussi un max de délai d'attente qui peut vous frapper. N'a rien à voir avec la taille, mais combien de temps votre requête post est à prendre...c'est à dire, combien de temps sa prend pour le fichier à envoyer. Les deux paramètres peuvent être contraints par IIS ou Apache.
OriginalL'auteur Gambit
D'autres l'ont déjà souligné qu'il y a des limites que vous rencontrerez sur toute la production de PHP serveur est correctement configuré. De mémoire, la poste, et le fichier maximums pour commencer. En outre, Le service httpd généralement restreint ces.
La réponse pour les téléchargements si grande serait de couper le fichier en segments, envoyer chaque morceau dans un autre put ou post (selon le navigateur).
Il y a une bibliothèque qui existe déjà, qui est capable de segmenter les uploads de fichier, je vais donc l'utiliser comme un exemple. À l'appui de fragments de téléchargement, le téléchargement de gestionnaire de fait de l'utilisation du Contenu de Gamme en-tête, qui est transmise par le plugin pour chaque morceau.
La handle_file_upload fonction dans le UploadHandler classe est un bon exemple de la façon de traiter un bloc de téléchargement de fichiers côté serveur avec PHP. -- https://github.com/blueimp/jQuery-File-Upload/blob/master/server/php/UploadHandler.php
La fonction prend l'argument
$content_range = null
qui est transmis au serveur dans l'en-tête HTTP, et de l'extrait de$_SERVER['HTTP_CONTENT_RANGE'];
Plus tard, nous avons besoin de savoir si nous serons en ajoutant le fichier de téléchargement d'un fichier qui existe déjà, nous avons donc créé une variable. Si les fichiers signalés taille de la requête HTTP est plus grande que la taille réelle du fichier sur le serveur, le
$content_range
variable n'est pas NULLE et que le fichier existe, nous aurons besoin d'ajouter ce téléchargement pour le fichier existant.Grand! Maintenant ce qui?
Alors maintenant, nous avons besoin de savoir combien nous sommes à recevoir les données. Les anciennes versions de Firefox ne pouvez pas utiliser multipart/formdata (POST) pour le bloc de téléchargement de fichiers. Ces demandes doivent être traitées différemment pour à la fois le client et côté serveur.
Selon la documentation: Chunked les téléchargements de fichiers sont pris en charge uniquement par les navigateurs avec support pour XHR les uploads de fichier et le Blob de l'API, qui comprend Google Chrome et Mozilla Firefox 4+ -- https://github.com/blueimp/jQuery-File-Upload/wiki/Chunked-file-uploads
Pour chunked télécharge de travailler dans Mozilla Firefox 4-6 (XHR capable de télécharger Firefox versions antérieures à Firefox 7), le multipart option doit également être définie sur false. Voici le code pour traiter les dossiers sur le serveur.
Et enfin nous pouvons vérifier que le téléchargement est terminé, ou de jeter à l'annulation de téléchargement.
Sur le côté client, vous aurez besoin de garder une trace de la des morceaux. Après chaque morceau est affiché nous envoyer la partie suivante jusqu'à ce qu'il n'y a pas plus de morceaux à gauche. L'exemple de la bibliothèque est un plugin pour jQuery qui le rend super simple. Nues XHR objets comme vous, elle va nécessiter un peu plus de code. Il pourrait ressembler à quelque chose comme ceci:
Boucle à travers les morceaux, le téléchargement de chaque morceau de gamme dans la tour. Notez que le Contenu de Gamme valeur d'en-tête est dans le format début-fin/taille. La gamme commence à 0, donc "fin" ne peut être au maximum de 1 à moins de "taille". Vous pouvez utiliser la gamme "démarrer" pour indiquer que la gamme s'étend de la fin du fichier de "démarrer".
EDIT:
Juste pensé que ce serait possible de mettre en place une barre de progression sur les serveurs où il n'est pas possible autrement pour unique de téléchargement de fichiers. Puisque vous connaissez la taille de chaque bloc, et le statut de chaque demande, vous pouvez mettre à jour une barre d'état en conséquence à chaque exécution de la boucle.
A noter également la limitation de certains navigateurs. Chrome et Firefox doit être capable de gérer un fichier de 4 go, mais les versions IE inférieur à 9 avait un bug qui empêchait la capacité de gérer des fichiers de plus de 2GB.
OriginalL'auteur NeoVance
Vous pouvez comparer votre code avec ce tutoriel. Ce tutoriel est capable de télécharger des fichiers de toute taille. Il est très similaire à votre code.
http://www.youtube.com/watch?v=pTfVK73CUk8
OriginalL'auteur Aditi
Je suis en train d'écrire sur l'étrange comportement de xhr.le téléchargement.chargé qui commence avec un grand nombre...
J'ai le même problème et je ne pouvais pas trouver la raison.
Le seul indice qui pourrait aider, c'est que selon le FAI le problème parfois disparaît!
par exemple, quand je test à partir de la maison, il fonctionne très bien et je ne vois pas ce comportement étrange, mais du travail de l'internet, le problème reste le même.
OriginalL'auteur skilledDeveloper
file_get_contents() retourne le contenu d'un fichier et le place dans un BUFFER en RAM avec un pointeur interne.
Si vous n'avez pas assez de ram, ou avez une version 32 bits d'apache/php, il peut se bloquer lorsque vous essayez d'allouer trop de mémoire.
Vous pouvez veux essayer quelque chose comme ceci à la place :
Acclamations
OriginalL'auteur Olivier St-L
J'ai essayé de télécharger un fichier vidéo de 4 GO à l'aide d'ajax. Il a été un succès.
Voici mon code.
HTML ::
CSS ::
Ajax ::
CÔTÉ SERVEUR ::
De changer également la liste figure ci-dessous php ini valeurs.
Si vous êtes sous linux/ubuntu - suivre les étapes
OriginalL'auteur Ijas Ahamed N