为什么我不能从POST请求中提取zip文件?

时间:2017-05-24 21:24:05

标签: javascript php google-drive-api zip docx

我有一段客户端代码,可以从Google云端硬盘导出.docx文件并将数据发送到我的服务器。它非常直接,它只是导出文件,使其成为blob,然后将blob发送到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);
});

这是我的服务器端代码,用于将此文件保存到我的服务器上,以便我可以使用它来执行操作:

<?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文件?

5 个答案:

答案 0 :(得分:5)

你应该首先下载原始zip,并将其内容与你在服务器上收到的内容进行比较,你可以这样做e.gg.使用totalcommander或行“diff”命令。

执行此操作时,您将看到在转移过程中是否更改了拉链。 有了这些信息,您可以继续搜索它为何被更改。 例如。当你在zipfile ascii 10转换为“13”或“10 13”时,它可能是文件传输中的行结束问题

因为当您使用fopen(..., 'r')在php中打开文件时,可能会发生这种情况,当您使用Windows时会转换符号,您可以尝试使用fopen(..., 'rb')强制BINARY读取文件而不转移行尾。

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

@see php documentation fopen

答案 1 :(得分:3)

我认为这可能取决于&#34; application / x-www-form-urlencoded&#34;。因此,当您使用php:// input读取请求数据时,它还会保存一些http属性,因此.zip已损坏。尝试打开.zip文件并查看其中的内容。 要修复,如果问题是我之前所说的尝试将Contenent-type更改为application / octet-stream。

答案 2 :(得分:2)

我建议使用base64在发布之前将二进制数据编码为文本流,之前我已经完成了它并且运行良好,使用二进制数据的url编码是行不通的。然后在您的服务器上进行64解码,以便在存储之前转换回二进制文件。

在base64中,您可以将其作为文本发布。

答案 3 :(得分:1)

好吧,对我而言,它不是一个ZIP文件。查看Drive API,您可以看到application/vnd.openxmlformats-officedocument.wordprocessingml.document未压缩,例如application/zip。您应该将文件作为DOCX处理。你试过了吗?

答案 4 :(得分:0)

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