Отправить файл с помощью 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
надеюсь, что это помогает.