为什么这个文件上传脚本有时会崩溃firefox并且在chrome中不起作用?

时间:2014-03-07 09:12:00

标签: jquery ajax file-upload blob

嗯,下面的代码看起来很长很复杂,但它很简单。

好的,这是我的HTML:

<input type="file" id="file_select" name="files[]"/>
<div id="upload_button">upload</div>
<div id="message"></div>

单击上传按钮后会触发preupload功能。它检查文件是否已存在于服务器上,稍后我将添加一些代码,以便继续取消下载(检查文件的某些部分是否已在服务器上,继续第一个缺失的部分)。

$(document).ready(function () {
    var start;
    var stop;                
    $('#upload_button').click(function (evt) {
        var file = $('#file_select')[0].files[0];        
        var chunk_size = 2048 * 1024; //2MB is the size of the parts
        var tot_parts = Math.ceil(file.size / chunk_size);
        preupload(file, tot_parts);
    });
});

这是preupload函数,如果文件不在服务器上,则启动文件上载:

function preupload(file, tot_parts) {    
    var fd = new FormData();
    fd.append('file_name', file.name);
    fd.append('file_size', file.size);
    fd.append('tot_parts', tot_parts);
    $.ajax({
        type: 'POST',
        url: 'file_preupload.php',
        data: fd,
        processData: false,
        contentType: false,
        success: function (result) {
            $("#message").html(result);
            if ($("#message").html() == "upload in progress") {                
                fileupload(file, tot_parts, 0, 2097152, 0);
            }
        }
    })
} 

这是preupload函数所针对的php脚本:

if(file_exists("uploads/".$_POST["file_name"]) && filesize("uploads/".$_POST["file_name"])==$_POST["file_size"]){
    echo "file exists already";
}
if(!file_exists("uploads/".$_POST["file_name"])){
    echo "upload in progress";
}

文件上传功能上传一个接一个的部分。上传最后一部分后,将触发上传后的功能。

function fileupload(file, tot_parts, start, stop, part) {                
    var reader = new FileReader();
    if (file.webkitSlice) {                    
        var blob = file.webkitSlice(start, stop);
    } else if (file.mozSlice) {
        var blob = file.mozSlice(start, stop);
    }
    reader.readAsBinaryString(blob);
    var fd = new FormData();
    fd.append('part', part);
    fd.append('file_name', file.name);
    fd.append('data', blob);
    fd.append('tot_parts', tot_parts);
    $.ajax({
        type: 'POST',
        url: 'file_upload.php',
        data: fd,
        processData: false,
        contentType: false,
        success: function (result) {
            console.log("result" + result);
            console.log("start" + start);
            console.log("stop" + stop);
            console.log("part" + part);
            if (part < tot_parts - 2) {
                start = stop;
                stop = stop + 2097152;
                part++;                            
                fileupload(file, tot_parts, start, stop, part);
            }
            if (part == tot_parts - 2) {
                start = stop;
                stop = file.size;
                part++;
                fileupload(file, tot_parts, start, stop, part);
                post_upload(file, tot_parts);
            }
        }
    })
}

这是文件上传的匹配php脚本:

if(!file_exists("uploads/".$_POST["file_name"])){
    if(isset($_POST)){
        $part=$_POST["part"];
        $target_path="uploads/".$_POST["file_name"]."_p4rt_".$_POST['part'];
        file_put_contents($target_path, file_get_contents($_FILES['data']['tmp_name']));
    }
}

最后两个脚本检查服务器上是否有所有部件并将它们再次组合在一起:

function post_upload(file,tot_parts) {
    var fd = new FormData();
    fd.append('file_name', file.name);
    fd.append('tot_parts', tot_parts);
    $.ajax({
        type: 'POST',
        url: 'file_postupload.php',
        data: fd,
        processData: false,
        contentType: false,
        success: function (result) {
            console.log('upload successful');
        }
    });
}

它的PHP脚本:

$part=(int)$_POST["tot_parts"]-1;
$last_part_name="uploads/".$_POST["file_name"]."_p4rt_".$part;
$content=array();
if(file_exists($last_part_name)){
    $file=fopen("uploads/".$_POST["file_name"], "x+");
    for($i=0; $i<=$part; $i++){
        if(file_exists("uploads/".$_POST["file_name"]."_p4rt_".$i)){
            array_push($content, file_get_contents("uploads/".$_POST["file_name"]."_p4rt_".$i));
            fwrite($file, $content[$i]);
        }
    }
    fclose($file);
    $all_parts=glob("uploads/".$_POST['file_name']."_*");
    foreach ($all_parts as $single_part) {
        unlink($single_part);
    }
}

事情是 - 如果firefox没有崩溃脚本工作。但我每隔一两次或第三次测试它 - 我的Firefox崩溃了。 firebug控制台中没有javascript错误。它不适用于Chrome。以下是Chrome控制台的错误:

  

未捕获的TypeError:无法执行'readAsBinaryString'   'FileReader':参数不是Blob。

通常情况下,webkitslice可以在Chrome中使用。或者什么可能导致错误? 以及如何调试firefox崩溃?任何想法,链接或其他任何东西?

1 个答案:

答案 0 :(得分:0)

第一件事webkitSlicemozSlice已被删除,您必须从过时的来源中获取示例。

您需要更改以下行

if (file.webkitSlice) {                    
    var blob = file.webkitSlice(start, stop);
} else if (file.mozSlice) {
    var blob = file.mozSlice(start, stop);
}

您可以通过传递相同的参数

来使用slice方法获取chuck
var blob = file.slice(start, stop);

资源