HTML5 File API readAsBinaryString считывает файлы намного большего размера, чем файлы на диске - PullRequest
8 голосов
/ 26 мая 2011

Полный код на https://gist.github.com/992562.

Я использую HTML File API и перетаскиваю их, чтобы загрузить файлы через сообщение XHR в сценарий PHP.Процедурно все работает нормально, однако, когда я пытаюсь открыть загруженные файлы, любой нетекстовый файл намного больше исходного файла и не открывается.Это явно не те данные, которые были на исходном диске.Тем не менее, текстовые файлы точно такие же и открываются просто отлично.

Некоторые примеры загрузки с помощью перетаскивания из трех файлов: файл 1: текст / XML: на диске 13 КБ, загружено 13 КБ, отлично работает файл2: изображение / PNG: на диске 14 КБ, загружено 18 КБ, не открывается файл 3: приложение / XLSX: на диске 12 КБ, загружено 14 КБ, не открывается

Все сводится кэто (после того, как xhr заголовки настроены, объект файла готов и т. д.):

  var reader = new FileReader();
  reader.onload = function(evt) {
    xhr.send(evt.target.result)
  }
  reader.readAsBinaryString(f);

возвращает большие, неверные данные.Что-то явно не так?

1 Ответ

25 голосов
/ 26 мая 2011

Вероятно, это потому, что вы читаете файл как двоичную строку и создаете запрос multipart/form-data вручную. Для одного вам не нужно использовать FileReader. Поскольку вы просто хотите отправить контент, попробуйте использовать xhr.send(File) или xhr.send(FormData). Последний создает и отправляет multipart/form-data для вас:

function uploadFiles(url, files) {
  var formData = new FormData();

  for (var i = 0, file; file = files[i]; ++i) {
    formData.append(file.name, file);
  }

  var xhr = new XMLHttpRequest();
  xhr.open('POST', url, true);
  xhr.onload = function(e) { ... };

  xhr.send(formData);  // multipart/form-data
}

document.querySelector('input[type="file"]').onchange = function(e) {
  uploadFiles('/server', this.files);
};
...