javascript 使用 XmlHttpRequest 发送文件:流式传输?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6454365/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Send a file with XmlHttpRequest: Streaming?
提问by linepogl
I am trying to upload big files with drag and drop. I have this piece of Javascript code:
我正在尝试通过拖放上传大文件。我有这段 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);
where url
is a string of the target url and file
is a Blob
(according to http://www.w3.org/TR/XMLHttpRequest2/#the-send-method) which I have retrieved after a file drag-drop. This code works in Chrome 12, Safari 5 and Firefox 4 and sends the raw contents of the file in the body of the HTTP request.
其中url
是目标 url 的字符串,file
是我在文件拖放后检索Blob
到的(根据http://www.w3.org/TR/XMLHttpRequest2/#the-send-method)。此代码适用于 Chrome 12、Safari 5 和 Firefox 4,并在 HTTP 请求正文中发送文件的原始内容。
However, if the file is big enough the request is never sent. Instead, the XMLHttpRequest
object fires and error event (without any useful message). This limit is 86Mb in my environment, but it varies from machine to machine.
但是,如果文件足够大,则永远不会发送请求。相反,XMLHttpRequest
对象会触发和错误事件(没有任何有用的消息)。在我的环境中这个限制是 86Mb,但它因机器而异。
The javascript console of Chrome shows the message:
Chrome 的 javascript 控制台显示消息:
POST http://localhost/xfiles/xfiles.php undefined (undefined)
which has nothing to do with my code (which works perfectly with smaller files).
这与我的代码无关(它适用于较小的文件)。
It seems that the browser reads the entire file in memory and before sending it. Probably there is an out of memory exception or something like that that stops the process. In any case, there no HTTP request is sent, so it is certain that the server's limits have nothing to do with this problem.
浏览器似乎在发送之前读取了内存中的整个文件。可能是内存不足异常或类似的东西会停止进程。无论如何,没有发送HTTP请求,因此可以肯定服务器的限制与此问题无关。
Anyway, reading the entire file is a waste of resources.
无论如何,读取整个文件是一种资源浪费。
Is there any method to send the file in a streaming fashion, byte by byte, without having to store it in the memory first?
是否有任何方法可以以流式方式逐字节发送文件,而不必先将其存储在内存中?
采纳答案by Na7coldwater
Try using the Blob.slice
method to split the Blob
up into multiple chunks, and send each one as a separate request.
尝试使用该Blob.slice
方法将其拆分Blob
为多个块,并将每个块作为单独的请求发送。
回答by Sandman4
Today, with chrome 31 (windows), xhr.send(file) will notread the whole file into memory. The fact is, I try to xhr.send 100mb file and look at task manager for chrome memory usage - it grows only slightly during 100mb file upload.
今天,使用 chrome 31 (windows), xhr.send(file)不会将整个文件读入内存。事实是,我尝试 xhr.send 100mb 文件并查看任务管理器以了解 chrome 内存使用情况 - 在 100mb 文件上传期间它仅略微增长。
As a side note, xhr.send(file)
fits better for PUT upload, for POST more appropriate would be FormData:
作为旁注,xhr.send(file)
更适合 PUT 上传,对于 POST 更合适的是 FormData:
var formData = new FormData();
formData.append("thefile", file);
xhr.send(formData);
Using FormData however, increases upload time by some 50% - probably because of the base64 encoding.
然而,使用 FormData 会将上传时间增加约 50% - 可能是因为 base64 编码。