使用 JavaScript 或 jQuery 拆分文件 [英] Split file with JavaScript or jQuery
问题描述
我需要上传文件的一部分(仅前 MB).我创建了一个上传整个文件的 PHP 脚本.数据(formData
对象)通过ajax 调用传递.
I need to upload a part of a file (only the first MB). I've created a PHP script which uploads the whole file. The data (formData
Object) is passed by a ajax call.
我的想法是现在用 javascript (jquery) 拆分文件.我的要求有什么解决方案吗?
My idea would be now to split the file with javascript (jquery). Is there any solution for my request?
当前代码:
function start(a){
//var fSize = $('#fileUpload')[0].files[0].size / 1024;
var formData = new FormData();
formData.append( 'fileUpload', $('#fileUpload')[0].files[0] );
//AJAX
$.ajax({
url: 'script.php',
type: 'POST',
data: formData,
processData: false,
contentType: false,
success: function(msg){
alert("Win: " + msg);
},
error: function(bla, msg){
alert("Fail: " + msg);
}
});
}
推荐答案
由于您使用的是 FormData
,这是一项相当新的技术,因此我也会向您展示一些新技术.
Since you're using FormData
, which is a fairly new technology, I'll show you something with new technologies as well.
首先,使用 FileReader
对象读取文件:
First, read the file with a FileReader
object:
var fr = new FileReader(), buf, file = $('#fileUpload')[0].files[0];
fr.onload = function(e) {
buf = new Uint8Array(e.target.result);
};
fr.readAsArrayBuffer(file);
然后你可以为每个分割的部分创建一个Blob
(每个1e6
字节长):
Then you can create a Blob
for each splitted part (1e6
bytes long each):
for (var i = 0, blobs = []; i < buf.length; i += 1e6)
blobs.push(new Blob([buf.subarray(i, i + 1e6)]));
最后,您可以将所有 Blob
添加到您的 FormData
对象中:
Finally, you can add all your Blob
s to your FormData
object:
var formData = new FormData();
for (var i = 0; i < blobs.length; i++)
formData.append("slice" + i, blobs[i], file.name + ".part" + i);
你应该没事.不过我还没有测试过.
You should be ok. I haven't tested it, though.
我对性能也一无所知.您也可以使用 fr.readAsBinaryString
,从而使 e.target.result
成为一个字符串.这样,您可以使用简单的 substring
/slice
/substr
/whatever 创建 Blob
s,但我担心 Unicode 字符和诸如此类的东西可能会出现一些问题.另外,也许它更慢.
I don't know anything about the performance either. You can use fr.readAsBinaryString
too, thus making e.target.result
a string. This way, you can create the Blob
s using a simple substring
/slice
/substr
/whatever, but I fear there could be some problems with Unicode characters and whatnot. Plus, maybe it's slower.
将所有内容放在一个更连贯的片段中:
Putting everything in a more coherent snippet:
$('#fileUpload').change(function() {
// If no file is selected, there's nothing to do
if (!this.files.length) return;
var fr = new FileReader(), file = this.files[0];
fr.onload = function(e) {
splitAndSendFile(new Uint8Array(e.target.result), file);
};
fr.readAsArrayBuffer(file);
};
function splitAndSendFile(dataArray, file) {
var i = 0, formData, blob;
for (; i < dataArray.length; i += 1e6) {
blob = new Blob([dataArray.subarray(i, i + 1e6)]);
formData = new FormData();
formData.append("fileUpload", blob, file.name + ".part" + (i / 1e6));
$.ajax({
url: 'script.php',
type: 'POST',
data: formData,
processData: false,
contentType: false,
success: function(msg){
alert("Win: " + msg);
},
error: function(bla, msg){
alert("Fail: " + msg);
}
});
}
}
注意:FormData.append
需要第三个可选参数,如果是File
或 应该是文件名>Blob
值.如果未指定,Blob
s 可能会获得不可预测的随机文件名.
Note: FormData.append
takes a third optional parameter, which should be the name of the file in case of File
or Blob
values. If not specified, Blob
s may get unpredictable random file names.
可能那个参数不是标准的,中没有提到MDN 文章,但我还是在上面的代码片段中使用了它.无论如何,如果您知道自己在做什么,则可以有多个选项来指定文件名.例如,使用 formData.append("filename", file.name)
或在请求中发送自定义标头.
Probably that parameter isn't standard, and it's not mentioned in the MDN artice, but I used it in the snippet above nonetheless. Anyway, if you know what you're doing, you can have several options to specify the file name. For example, with formData.append("filename", file.name)
or sending a custom header in the request.
这篇关于使用 JavaScript 或 jQuery 拆分文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!