2017-05-24 1 views
8

J'ai un code client qui exporte un fichier .docx de Google Drive et envoie les données à mon serveur. C'est assez simple, il exporte juste le fichier, le transforme en blob et envoie le blob à un point de terminaison POST.Pourquoi ne puis-je pas extraire un fichier zip d'une demande POST?

gapi.client.drive.files.export({ 
    fileId: file_id, 
    mimeType: "application/vnd.openxmlformats-officedocument.wordprocessingml.document" 
}).then(function (response) { 

    // the zip file data is now in response.body 
    var blob = new Blob([response.body], {type: "application/vnd.openxmlformats-officedocument.wordprocessingml.document"}); 

    // send the blob to the server to extract 
    var request = new XMLHttpRequest(); 
    request.open('POST', 'return-xml.php', true); 
    request.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); 
    request.onload = function() { 
     // the extracted data is in the request.responseText 
     // do something with it 
    }; 

    request.send(blob); 
}); 

Voici mon code côté serveur pour enregistrer ce fichier sur mon serveur afin que je puisse faire des choses avec elle:

<?php 
file_put_contents('tmp/document.docx', fopen('php://input', 'r')); 

Quand je lance cela, le fichier est créé sur mon serveur. Cependant, je crois qu'il est corrompu, parce que quand je tente de le décompresser (comme vous pouvez le faire avec .docx), cela se produit:

$ mv tmp/document.docx tmp/document.zip 
$ unzip tmp/document.zip 
Archive: document.zip 
error [document.zip]: missing 192760059 bytes in zipfile 
    (attempting to process anyway) 
error [document.zip]: start of central directory not found; 
    zipfile corrupt. 
    (please check that you have transferred or created the zipfile in the 
    appropriate BINARY mode and that you have compiled UnZip properly) 

Pourquoi est-ce pas le reconnaître comme un fichier .zip approprié?

+0

Note pour le futur lecteur: Je ne sais pas encore comment faire.Je pense que j'essayais juste trop fort d'insérer une cheville en forme de fichier zip dans un trou en forme de jeton. Ainsi, j'ai restructuré l'application pour faire les appels d'exportation de gapi sur le backend et faire des choses avec les données extraites là. –

Répondre

3

Je pense que cela dépend de "application/x-www-form-urlencoded". Ainsi, lorsque vous lisez les données de requête avec l'entrée php: //, cela enregistre aussi une propriété http, donc le .zip est corrompu. Essayez d'ouvrir le fichier .zip et regardez ce qu'il y a à l'intérieur. Pour corriger, si le problème est ce que j'ai déjà dit, essayez de changer le type Contenent en application/octet-stream.

+0

Comment recommandez-vous d'ouvrir le fichier zip pour voir ce qu'il y a dedans? Je ne peux pas le décompresser ... –

+1

Je ne parle pas de décompresser Il, essayez de le regarder avec un hexdumper (ou un éditeur normal, juste ti voir s'il y a des données http post) –

+0

Il n'apparaît pas que 'php: // input' contient des informations de réponse. Changer le type de contenu à 'application/octet-stream' n'a rien fait :( –

5

Vous devez d'abord télécharger le zip d'origine, et comparer son contenu à ce que vous recevez sur votre serveur, vous pouvez le faire par exemple. avec la commande totalcommander ou line "diff".

Lorsque vous faites cela, vous verrez si votre zip est modifié pendant le transfert. Avec cette information, vous pouvez continuer à chercher POURQUOI il est changé. E.g. quand en vous ZipFile ascii 10 est transformé en « 13 » ou « 10 13 », il pourrait y avoir une fin de ligne problème sur le transfert de fichiers

Parce que quand vous ouvrez des fichiers en php avec fopen(..., 'r') il peut arriver que \ n signes sont Transformé lorsque vous utilisez Windows, vous pouvez essayer d'utiliser fopen(..., 'rb') qui impose BINARY lire un fichier sans transférer les fins de ligne.

@see: https://stackoverflow.com/a/7652022/2377961

documentation @see php fopen

2

Je suggère d'utiliser base64 pour coder les données binaires dans un flux de texte avant de poster, je l'ai déjà fait et il fonctionne bien, en utilisant L'encodage de l'URL pour les données binaires ne fonctionnera pas. Ensuite, sur votre serveur, vous décoderez 64 base pour convertir en binaire avant de stocker.

Une fois son en base64, vous pouvez l'afficher en tant que texte.

1

Eh bien, pour moi ce n'est pas un fichier ZIP. En regardant le Drive API, vous pouvez voir que application/vnd.openxmlformats-officedocument.wordprocessingml.document n'est pas zippé, comme application/zip est. Vous devriez gérer le fichier en DOCX, je pense. Avez-vous essayé cela?

+0

Oui, lorsque j'exporte le fichier sous forme de fichier .docx localement, je peux extraire juste comme un fichier zip –

+0

Ok, je ne savais pas que docx peut être décompressé !! Merci! – Saleiro

0

Vous envoyez un BLOB (fichier binaire) en utilisant "Content-type", "application/x-www-form-urlencoded" sans codage d'URL appliqué au BLOB ... donc, le fichier que PHP reçoit n'est pas un fichier ZIP, c'est un fichier corrompu. Changez le "Content-type" ou appliquez l'URL en BLOB. Vous pouvez avoir une meilleure idée en regardant MDN - Sending forms through JavaScript. Ces questions devraient aider aussi: question 1, question 2. Vous devez envoyer le fichier correctement.