我正在将视频文件上传到我的服务器。文件至少为20MB,有些超过100MB。
为了改善用户体验,我通过JavaScript和XMLHttpRequest上传,这样我就可以显示上传速度和剩余时间。
为避免服务器上的麻烦(例如请求超时和处理时间过长),我在服务器上的小包中提交文件,然后让php脚本重新组装文件。
我的脚本效果很好,有一个奇怪的问题 - 直到现在我才认为这是因为我的ISP。
使用Google Chrome我可以上传最大20MB的文件,没有任何问题。但是任何更大的错误都会产生错误:例如我的100MB文件不会向服务器发送任何内容 - 第二个包永远不会到达。在我的50MB文件中,它发生在大约47%之后,第7个包。而另一个文件甚至不发送第一个包。
我重新启动了我的计算机,并且每个文件的位置/包的编号都相同 - 尽管该位置与其他失败的文件相比没有任何共同点。
如果你尝试在其中一个失败的软件包之后启动它并不重要,比如说如果我从#8开始,如果7失败 - 它将继续失败。如果我忽略错误(而不是再次尝试),它将以空块的形式发送文件的其余部分。
我已经尝试过不同的互联网连接,但我不得不在那里使用firefox。它工作得很好。所以我在我的机器上安装了firefox,BAM就像魅力一样,正确发送100MB文件。
Chrome上可能出现什么问题?
$(document).on('click','#video_upload',function(evt){
uploadProcess('vod_video_file');
});
function toBlob(text)
{
var data = new ArrayBuffer(text.length);
var ui8a = new Uint8Array(data, 0);
for (var i = 0; i < text.length; i++) ui8a[i] = (text.charCodeAt(i) & 0xff);
if(typeof window.Blob == "function")
{
var blob = new Blob([data]);
}else{
var bb = new (window.MozBlobBuilder || window.WebKitBlobBuilder || window.BlobBuilder)();
bb.append(data);
var blob = bb.getBlob();
}
return blob;
}
function splitFile(dataArray, size) {
blobs = new Array();
for (var i = 0; i < dataArray.size; i += size)
{
var copy = dataArray.slice();
var partial = copy.slice(i, i+size);
blobs.push(partial);
}
return blobs;
}
function uploadProcess(fileInputId)
{
var file = document.getElementById(fileInputId).files[0];
var reader = new FileReader();
reader.readAsBinaryString(file);
reader.onloadend = function(evt)
{
var fr = evt.target.result;
fileUpload( fr );
}
}
function fileUpload(inputDataArray)
{
var since;
var intervalid;
var totalBytes = inputDataArray.length;
var packets = new Array();
var packetNum = 0;
var packetCount = 0;
var packetSize = 0;
function startUpload()
{
intervalid = setInterval(function(){updateUploadStats();},1000);
calculatePaketSize()
createPackets();
submitPacket();
}
function calculatePaketSize()
{
var ideal_size = 3*1024*1024;
var packet_count = Math.ceil( totalBytes/ideal_size);
packetSize = Math.ceil(totalBytes/packet_count);
}
function createPackets()
{
packets = splitFile(toBlob(inputDataArray), packetSize)
packetCount = packets.length;
}
function updateUploadStats(e)
{
//displaying upload progress in GUI
}
function submitPacket()
{
xhr = new XMLHttpRequest();
xhr.open("POST", 'index.php?controller=AdminVodVideo&action=VideoUpload&ajax=1&r='+packetNum+'&token='+token, true);
xhr.setRequestHeader("Content-type","application/octet-stream");
XMLHttpRequest.prototype.mySendAsBinary = function(text){
this.send(text);
}
var eventSource = xhr.upload || xhr;
eventSource.addEventListener("progress", function(e) {
updateUploadStats(e);
});
xhr.onreadystatechange = function()
{
if(xhr.readyState == 4)
{
if(xhr.status == 200)
{
//server will return the string 'upload failed' if the file to be received was empty.
if( xhr.responseText == 'upload failed')
{
console.log('FAILED , trying again in 3 s');
setTimeout(submitPacket,3000);
}
else
{
updateUploadStats();
packetNum++;
if(packetNum == packetCount)
{
processOnServer();
}
else
{
submitPacket();
}
}
}else{
// process error
console.log('we got a 500 error');
}
}
};
since = Date.now();
xhr.mySendAsBinary( packets[packetNum] );
}
function processOnServer()
{
//telling the server to piece the file back together.
}
startUpload();
}
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
&#13;