我只在Google Chrome和Chromium上遇到了一个非常奇怪的问题。
背景是:
我使用分块上传法将文件上传到我的服务器,这意味着我将文件分成10mb的块,并将每个块发送到服务器。这在所有浏览器中都能完美地处理任何大小的文件,当我需要加密每个块时,这个问题就开始了。
对于加密,我使用CryptoJS,在上传数据块之前,我对其进行加密,并获得上传的Blob
,当我必须上传少于50个数据块(50个blobs,总共大约500mb )时,这在Chrome上运行得很好,然后我得到一个POST http://(...) net::ERR_FILE_NOT_FOUND
。
奇怪的是,这可以在所有其他浏览器上运行,包括Opera,它现在基本上就是Chrome,除了Chrome和Chromium。我在IE,Firefox,Edge,Safari,Opera,Chrome和Chromium上测试了它。
下面你可以看到我的代码是如何工作的,所以你们可以有一个想法,这不是我在应用程序中使用的真实代码,而是我编写的测试代码,产生了相同的结果。
我将生成一个与我的块大小相同的假blob
,而不是获取我要作为块上传的文件的切片(File.slice
)并对其进行加密以获得blob
。我将setTimeout
用于模拟加密blob所需的时间。就像我之前说的,通过这样做,我得到了与我的真实代码相同的结果:
function uploadNext(prevResponse) {
if (currentPart == totalPartsFile)
return;
//var chunk = getNextChunk();
var totalSize = file.size;
setTimeout(function() {
var blob = new Blob([new ArrayBuffer(constants.chunkSize)], {
type: 'application/octet-string',
name: file.name
});
console.log(blob);
blob.encrypted = true;
blob.key = encryptionKey;
blob.mimeType = file.mimeType;
blob.name = file.name;
blob.originalFileSize = originalFileSize || file.size;
uploadFile(objectId, currentPart, blob, totalSize, prevResponse, function(resp) {
uploadNext(resp);
});
}, 1000);
}
所以,上面的代码是我的blob生成的地方,下面是上传部分:
function uploadFile (objectId, index, blob, totalSize, prevResponse, callback) {
var format = "encrypted";
var params = "?format=" + format + (format === "encrypted" ? "&encoding=base64" : "");
var endPoint = constants.contentServiceUrl + resourceService.availableResources.addContents.link.split(':objectId').join(objectId) + params;
var formData = new FormData();
formData.append("totalFileSizeBytes", totalSize);
formData.append("partIndex", index);
formData.append("partByteOffset", previousOffset);
formData.append("chunkSize", blob.size);
formData.append("totalParts", totalPartsFile);
formData.append("filename", blob.name);
if (currentPart != 0) {
formData.append("uploadId", prevResponse.uploadId);
formData.append("bucket", prevResponse.bucket);
}
if (finalChunk) {
for (var key in etags1) {
formData.append("etags[" + key + "]", etags1[key]);
}
}
formData.append("data", blob);
previousOffset += blob.size;
var request = {
method: 'POST',
url: endPoint,
data: formData,
headers: {
'Content-Type': 'multipart/form-data'
}
}
$http(request)
.success(function(d) {
_.extend(etags1, d.etags);
console.log(d);
callback(d);
})
.error(function(d) {
console.log(d);
});
}
当然还有其他的支持变量和代码,我没有放在这里,但这足以让我们对我们正在处理的东西有一个概念。
在本例中,我使用了AngularJS的$http
模块,但我也尝试了纯XMLHttpRequest
,并得到了相同的结果。
就像我说过的,我只能在Chrome上获得大于499mb的文件(50+块)的POST http://(...) net::ERR_FILE_NOT_FOUND
。
我在这里发布了这篇文章,因为我一直在寻找解决方案,但我找不到任何与这个问题相关的东西,我在互联网上找到的最接近的东西是Chromium项目论坛中的这个问题:
https://code.google.com/p/chromium/issues/detail?id=375297
在这一点上,我真的不知道该怎么做了,所以我想知道是否有人在过去遇到过类似的问题,并能以某种方式解决它。
提前感谢您的回答。
发布于 2017-05-05 14:57:35
chrome只能为任何blob分配500mb,所以如果你尝试分配500mb +1字节,它显然会忽略这个字节,为了解决这个问题,你必须以499mb的块读取文件,然后你必须在服务器上合并文件。
或者你可以尝试像ZipJS这样的东西,然后上传压缩包,它对我很有效。
var zip = new JSZip();
zip.file("file1", "content1");
zip.file("file2", "content2");
发布于 2016-06-01 18:36:36
似乎,这是Firebug插件的问题。试着禁用它。这对我很管用。
Firefox浏览器。当我按块加载文件时,我遇到了问题。我禁用了插件,没有出现内存泄漏。也许它会对你有帮助
对于Chrome来说,一切都很好。
https://stackoverflow.com/questions/34780926
复制相似问题