2017-05-24 110 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。您必須正確發送文件。