2017-05-24 13 views
8

Mam fragment kodu po stronie klienta, który eksportuje plik .docx z Dysku Google i wysyła dane do mojego serwera. Jest całkiem prosty, po prostu eksportuje plik, przekształca go w obiekt typu blob i wysyła kropelkę do punktu końcowego POST.Dlaczego nie mogę wyodrębnić pliku zip z żądania 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); 
}); 

Oto mój serwer kodu po stronie, aby zapisać ten plik na moim serwerze, więc mogę robić rzeczy z nim:

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

Kiedy uruchamiam ten plik jest tworzony na moim serwerze. Uważam jednak, że jest uszkodzony, bo gdy próbuję go rozpakować (jak można zrobić z .docx), tak się dzieje:

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

Dlaczego nie jest to uznając go jako prawidłowego pliku .zip?

+0

Uwaga dla przyszłego czytelnika: Nadal nie jestem pewien, jak to zrobić.Myślę, że po prostu starałem się zbyt mocno, aby dopasować kołek w kształcie pliku zip do dziury w kształcie znaku dostępu. Tak więc zrestrukturyzowałem aplikację, aby wywoływać wywołania luki w zapleczu i robić tam dane z wyodrębnionych danych. –

Odpowiedz

3

Myślę, że to może zależeć od tego "application/x-www-form-urlencoded". Więc kiedy odczytasz dane żądania za pomocą php: // input, zapisujesz również pewną właściwość http, więc plik .zip jest uszkodzony. Spróbuj otworzyć plik .zip i sprawdź, co jest w środku. Aby naprawić, jeśli problem jest, co powiedziałem wcześniej, spróbuj zmienić Contenent-type na application/octet-stream.

+0

Jak polecasz otwarcie pliku zip, aby zobaczyć, co jest w środku? Nie mogę tego rozpakować ... –

+1

Nie mówiłem o rozpakowaniu go, spróbuj spojrzeć na to za pomocą hexdumpera (lub normalnego edytora, po prostu zobacz, czy są jakieś dane postów http) –

+0

Nie pojawia się że 'php: // input' zawiera jakiekolwiek informacje odpowiedzi. Zmiana typu zawartości na 'application/octet-stream' nic nie dała :( –

5

Najpierw należy pobrać oryginalny zip i porównać jego zawartość z tym, co można otrzymać na serwerze, można to zrobić na e.gg. z poleceniem totalcommander lub line "diff".

Gdy to zrobisz, zobaczysz, czy twój kod pocztowy zostanie zmieniony podczas przesyłania. Dzięki tym informacjom można kontynuować wyszukiwanie DLACZEGO zostanie zmieniony. E.g. kiedy w tobie plik zipfile ascii 10 jest przekształcany na "13" lub "10 13" może to być problem z kończeniem linii na transferze pliku

Ponieważ po otwarciu plików w php z fopen(..., 'r') może się zdarzyć, że \ n znaki są przekształcone podczas korzystania z systemu Windows, można spróbować użyć polecenia fopen(..., 'rb'), które wymusza BINARY odczytywanie pliku bez przenoszenia zakończenia linii.

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

dokumentacja @see php fopen

2

Chciałbym zasugerować używając base64 do kodowania danych binarnych do strumienia tekstu przed wysłaniem, robiłem to już wcześniej i to działa dobrze, z wykorzystaniem kodowanie URL dla danych binarnych nie zadziała. Następnie na twoim serwerze opierasz 64 dekodowanie, aby przekonwertować z powrotem na binarny przed zapisaniem.

Po jego założeniu w base64 można go opublikować jako tekst.

1

Cóż, dla mnie nie jest to plik ZIP. Patrząc na Drive API widać, że application/vnd.openxmlformats-officedocument.wordprocessingml.document nie jest spakowany, jak na przykład application/zip. Powinieneś traktować plik jako DOCX, jak sądzę. Czy próbowałeś tego?

+0

Tak, kiedy eksportuję plik jako .docx lokalnie mogę wyodrębnić tak jak plik zip. –

+0

Ok, nie wiedziałem, że docx może być rozpakowany! Dzięki! – Saleiro

0

Wysyłasz BLOB (plik binarny) używając "Content-type", "application/x-www-form-urlencoded" bez kodowania adresu URL stosowanego na BLOB ... tak, plik, który PHP otrzymuje nie jest plikiem ZIP, jest uszkodzony. Zmień "Typ zawartości" lub zastosuj adres URL do BLOB. Możesz uzyskać lepszy pomysł patrząc na MDN - Sending forms through JavaScript. Te pytania również powinny pomóc: question 1, question 2. Musisz wysłać plik poprawnie.

Powiązane problemy