2013-11-29 4 views
4

Мы реализуем клиентское веб-приложение, которое общается с сервером исключительно через XMLHttpRequests (и движок AJAX).Ответ AJAX дает поврежденный сжатый файл (.tgz)

Ответы XHR обычно представляют собой обычный текст с некоторым XML-кодом, но в этом случае сервер отправляет сжатые данные в .tgz-тип файла. Мы точно знаем, что данные, отправляемые сервером, верны, потому что, если мы используем клиент командной строки HTTP, такой как завиток, файл, отправленный как ответ, действителен и содержит ожидаемые данные.

Однако при выполнении вызова AJAX и «раскачивании» ответа в загружаемом файле полученный файл отличается по размеру (выше), чем правильный, и он не распознается декомпрессором. Это дает следующее сообщение об ошибке:

gzip: stdin: not in gzip format 
/bin/gtar: Child returned status 1 
/bin/gtar: Error is not recoverable: exiting now 

кодом я использую следующее:

*$.AJAX*.done(function(data){ 
    window.URL = window.webkitURL || window.URL; 
    var contentType = 'application/x-compressed-tar'; 
    var file = new Blob([data], {type: contentType}); 
    var a = document.createElement('a'), 
    ev = document.createEvent("MouseEvents"); 
    a.download = "browser_download2.tgz"; 
    a.href = window.URL.createObjectURL(file); 
    ev.initMouseEvent("click", true, false, self, 0, 0, 0, 0, 0, 
      false, false, false, false, 0, null); 
    a.dispatchEvent(ev); 
}); 

Я избегал параметров, используемых, чтобы сделать вызов AJAX, но давайте предположим, что это не проблема как я правильно получаю ответ. Я использовал этот contentType, потому что тот же самый, который был получен с помощью curl, но я попробовал разные. Код может выглядеть немного странно, поэтому я его раскрою: я в основном создаю ссылку, и я прикрепляю к ней ссылку для загрузки и имя файла (это грязный способ назвать файл). Наконец, я практически щелкаю ссылку.

Я сравнил правильный файл tgz и тот, который был получен через браузер с шестнадцатеричным просмотром, и я наблюдал повторение шаблонов в поврежденном (EF, BF и BD, все вместе с файлом), который отсутствует в правильном один.

Поэтому я думаю о некоторых возможных причинах:

(a) The browser is adding extra characters or maybe the response header is still in the downloaded file.

(b) The file has been partially decompressed because when I inspect the request Header I can state "Accept-Encoding: gzip, deflate"; although I don't know if the browser (Firefox in my case) automatically decompresses data.

(c) The code that I'm using to blob the data is not correct; although it acomplished well the aim with a plain/text file in another occasion.

Редактировать

Я также предоставить вам ссылки на шестигранную проверки:

(а) Поврежденный файл: http://en.webhex.net/view/278aac05820c34dfbdd2217c03970dd9/0 (b) (Предположительно) правильный файл: http://en.webhex.net/view/4a01894b814c17d2ec71ba49ac48e683

ответ

10

I не знаю, будет ли этот поток полезен для кого-то, но на всякий случай я выяснил причину и возможное решение моей проблемы.

Причина

По умолчанию Javascript переменные хранят информацию в формате/ASCII Unicode; они не готовы правильно хранить двоичные данные, и поэтому можно легко увидеть неверные интерпретируемые символы (это также объясняет, почему повторения EF, BF и т. д. наблюдались в Hex Viewer, которые обозначают неправильные символы ASCII/Unicode) ,

Раствор

Последние версии браузеров реализовать так называемые типизированные массивы. Это javascript-массивы, которые могут хранить данные в разных форматах (также двоичные). Затем, если указывается, что ответ XMLHttpRequest находится в двоичном формате, данные будут правильно сохранены и, когда они будут записаны в файл, файл не будет поврежден.Проверьте код, который я использовал:

var xhr = new XMLHttpRequest(); 
xhr.open('POST', url, true); 
xhr.responseType = 'arraybuffer'; 

Обратите внимание, что ключевым моментом является определение responseType как «ArrayBuffer». Также может быть интересно заметить, что я решил больше не использовать JQuery для AJAX. Он плохо реализует эту функцию, и все попытки, которые я делал для разбора Jquery, были напрасны (overrideMimeType, описанный где-то еще, не работал в моем случае). Вместо этого старый простой XMLHttRquest работал довольно красиво.

+0

Все еще полезно в 2015 году! – rdnewman

Смежные вопросы