使用 JavaScript 或 jQuery 拆分文件
Posted
技术标签:
【中文标题】使用 JavaScript 或 jQuery 拆分文件【英文标题】:Split file with JavaScript or jQuery 【发布时间】:2012-08-16 19:54:36 【问题描述】:我需要上传文件的一部分(只有第一个 MB)。我创建了一个上传整个文件的 php 脚本。数据 (formData
Object) 通过 ajax 调用传递。
我的想法是现在用 javascript (jquery) 拆分文件。我的请求有什么解决方案吗?
当前代码:
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);
);
【问题讨论】:
您无权访问 JavaScript 中的内容文件。没有办法拆分它。顺便说一句,也无法使用 AJAX 发布文件。 @RoToRa 你为什么不把它作为答案发布? @RoToRa 好吧,实际上有一种方法 - 使用新的FileReader API。但不知何故,我认为这与这里无关。 ) @user1515190 我想this article 可能对你有帮助。但请注意,其中使用的工具尚未得到普遍支持……。 @RoToRa ehm,上面的脚本有效。 【参考方案1】:由于您使用的是FormData
,这是一项相当新的技术,所以我也会向您展示一些新技术。
首先,读取带有FileReader
对象的文件:
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
字节长):
for (var i = 0, blobs = []; i < buf.length; i += 1e6)
blobs.push(new Blob([buf.subarray(i, i + 1e6)]));
最后,您可以将所有Blob
s 添加到您的FormData
对象中:
var formData = new FormData();
for (var i = 0; i < blobs.length; i++)
formData.append("slice" + i, blobs[i], file.name + ".part" + i);
你应该没事的。不过我还没有测试过。
我也对表演一无所知。您也可以使用fr.readAsBinaryString
,从而使e.target.result
成为一个字符串。这样,您可以使用简单的substring
/slice
/substr
/whatever 创建Blob
s,但我担心 Unicode 字符之类的可能会出现一些问题。另外,也许它更慢。
将所有内容放在一个更连贯的 sn-p 中:
$('#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 可能会得到不可预知的随机文件名。
可能这个参数不是标准的,在MDN artice中也没有提到,但我还是在上面的sn-p中使用了它。无论如何,如果你知道你在做什么,你可以有几个选项来指定文件名。例如,使用formData.append("filename", file.name)
或在请求中发送自定义标头。
【讨论】:
感谢您的回复。我不想发送整个数组,只是部分发送(所以我可以控制进度条),但不知何故它不起作用(最后链接到我的脚本)。我的 PHP 脚本是一个简单的命令(move_uploaded_file($_FILES["fileUpload"]["tmp_name"], $uploadPath . $_FILES["fileUpload"]["name"]);)。我想在服务器端将零件组装在一起。 193.109.52.60/dario/f @user1515190 由于blob.push(...
行中的语法错误,它不起作用。错过了一个右括号,我的错。你可以再试一次。
仍然无法正常工作:/ PS:非常感谢您的帮助!我尝试了几个星期(当然不是全职:D)
@user1515190 啊,我明白了。现在问题出在 您的 代码中。我没有把所有的东西都放在一个完整的形式中,但它不能以同步的方式完成。我会在答案中给你一个提示。
还是有些不对劲。我试图用警报调试我的代码。警报 6 不出现(在此代码部分之后:blob = new Blob([dataArray.subarray(i, i + 1e6)]);以上是关于使用 JavaScript 或 jQuery 拆分文件的主要内容,如果未能解决你的问题,请参考以下文章
Javascript / Jquery 将变量拆分为两个以进行条带集成