2017-05-24 181 views
8

我有一段客户端代码,用于从Google Drive中导出.docx文件并将数据发送到我的服务器。它非常简单直接,它只是导出文件,将其放入Blob中,并将Blob发送到POST端点。为什么我无法从POST请求中提取zip文件?

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); 
}); 

这里是我的服务器端代码到这个文件保存到我的服务器,所以我可以做的事情吧:

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

当我运行此,我的服务器上创建的文件。不过,我相信它已损坏,因为当我尝试将它解压缩(你可以用.DOCX做到),出现这种情况:

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

为什么没有认识到它作为一个适当的.zip文件?

+0

未来读者注意:我仍然不知道如何做到这一点。我想我只是努力将一个拉链文件形状的钉子插入一个存取令牌形状的孔中。所以,我重组了应用程序,在后端进行gapi导出调用,并在那里处理提取的数据。 –

回答

3

我认为这可能取决于“application/x-www-form-urlencoded”。所以当你用php://读取请求数据时,它也会保存一些http属性,所以它的.zip已经损坏。尝试打开.zip文件并查看里面的内容。 要修复,如果问题是我之前说过的,试着将Contenent-type更改为application/octet-stream。

+0

你如何建议打开zip文件来查看里面有什么?我不能解压缩它... –

+1

我没有谈到解压缩它,试着看看它与一个hexdumper(或普通的编辑器,只是看看是否有一些http后数据) –

+0

它不会出现'php:// input'包含任何响应信息。将内容类型改为'application/octet-stream'没有做任何事情:( –

5

你应该先下载原始的zip文件,并将其内容与你在服务器上收到的内容进行比较,你可以做到这一点egg。用totalcommander或line“diff”命令。

当你这样做的时候,你会看到你的压缩文件是否在传输过程中发生变化。 有了这些信息,您可以继续搜索为什么它被更改。 例如当你在zipfile ascii 10被转换为“13”或“10 13”时,它可能是文件传输中的行结束问题

因为当你在php中用fopen(..., 'r')打开文件时,可能会发生\ n符号当你使用Windows时,你可以尝试使用fopen(..., 'rb'),它强制读取一个文件而不用传送行尾。

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

@see PHP文件fopen

2

我会建议使用Base64发布前用于编码的二进制数据转换成文本流,我以前做过,效果很好,使用二进制数据的网址编码不会起作用。然后在您的服务器上进行64位解码,然后在存储之前转换回二进制文件。

一旦它在base64中,您可以将它作为文本发布。

1

那么,对我来说这不是一个ZIP文件。看看Drive API你可以看到application/vnd.openxmlformats-officedocument.wordprocessingml.document没有压缩,就像application/zip是。我认为你应该把文件当作DOCX来处理。你尝试过吗?

+0

是的,当我将文件导出为.docx在本地我可以提取就像一个zip文件 –

+0

好吧,我不知道,docx可以解压缩!谢谢! – Saleiro

0

您正在使用"Content-type", "application/x-www-form-urlencoded"发送一个BLOB(二进制文件),并且没有在BLOB上应用URL编码...因此,PHP接收的文件不是ZIP文件,而是损坏的文件。更改“Content-type”或将URL应用于BLOB。你可以看看MDN - Sending forms through JavaScript更好的主意。这个问题也应该有帮助:question 1,question 2。您必须正确发送文件。

相关问题