Отправить файл с помощью XMLHttpRequest: Streaming?

Я пытаюсь загрузить большие файлы с помощью перетаскивания. У меня есть этот фрагмент кода Javascript:

xhr = new XMLHttpRequest();
xhr.open('POST', url, true);
xhr.setRequestHeader('X-File-Name', file.name);
xhr.setRequestHeader('X-File-Size', file.size);
xhr.setRequestHeader('Content-Type', file.type);
xhr.send(file);

здесь url - это строка целевого url и file - это Blob (согласно http://www.w3.org/TR/XMLHttpRequest2/#the-send-method), который я получил после перетаскивания файла. Этот код работает в Chrome 12, Safari 5 и Firefox 4 и отправляет сырое содержимое файла в теле HTTP-запроса.

однако, если файл достаточно большой запрос никогда не отправляется. Вместо XMLHttpRequest объект срабатывает и событие ошибки (без какого-либо полезного сообщения). Этот предел составляет 86Mb в моей среде, но он варьируется от машины к машине.

консоль javascript Chrome показывает сообщение:

POST http://localhost/xfiles/xfiles.php undefined (undefined)

который не имеет ничего общего с моим кодом (который отлично работает с меньшими файлами).

кажется, что браузер читает весь файл в памяти и перед его отправкой. Вероятно, есть исключение из памяти или что-то в этом роде, что останавливает процесс. В любом случае HTTP-запрос не отправляется, поэтому очевидно, что ограничения сервера не имеют ничего общего с этой проблемой.

в любом случае,чтение всего файла является пустой тратой ресурсов.

есть ли способ отправить файл потоковым способом, байт за байтом, без необходимости сначала хранить его в памяти?

3 ответов


попробуйте использовать Blob.slice метод разделения Blob вверх в несколько кусков и отправить каждый из них в качестве отдельного запроса.


сегодня, с chrome 31 (windows), xhr.отправить(файл) будет не читать весь файл в память. Дело в том, что я пытаюсь xhr.отправьте файл 100mb и посмотрите на Диспетчер задач для использования памяти chrome - он растет только немного во время загрузки файла 100mb.

в качестве примечания,xhr.send(file) подходит лучше для PUT upload, для POST более подходящим будет FormData:

  var formData = new FormData();
  formData.append("thefile", file);
  xhr.send(formData);

использование FormData однако увеличивает время загрузки примерно на 50% - вероятно, из-за base64 кодирование.


проверьте этот плагин jquery, если вы используете jQuery http://github.com/valums/file-uploader

надеюсь, что это помогает.