多文件上传 - 通过Ajax-request检查服务器上存在哪些文件

时间:2012-12-03 16:26:23

标签: javascript ajax file-upload multiple-files

我似乎无法找到这个脚本的想法有什么问题,并且无法让它工作。也许你可以帮助我,我们将非常感激。

我正在处理多文件上传表单。 在上传之前(而不是之前),我想检查上传目录中是否存在某些文件(如果是,哪些文件)。 我正在使用XMLHttpRequests来做到这一点。由于我无法控制那些获取响应需要多长时间,因此我使用数组为所有变量运行循环,因此它们(至少这是我的想法;-))可以独立完成彼此的工作。

function NoOverwrite() {
var fields = document.querySelectorAll("input[type=file]");
var existing = new Array(); //files existing on server
var checkFile = new Array();
var file = new Array();
var fileUrl = new Array();
for (var i = 0; i < fields.length; i++) {
    file[i] = document.getElementById('file'+i).files[0];  
    //the input- fields of the form are called file0, file1, file2, and so on...
    if(file[i]) {
        fileUrl[i] = 'upload_path/' + file[i].name; 
        //up to here everything works fine - when setting an alert after this I get 
        //the names of all the names of the files selected in the file fields! 
        checkFile[i] = new XMLHttpRequest();
        checkFile[i].open('HEAD', fileUrl[i], true);
        checkFile[i].onreadystatechange = function() {
            if (checkFile[i].readyState == 4) {
                if (checkFile[i].status == 200) {
                    existing[i] = true; 
                    alert(existing[i]);     //this never came up... 
                }
            }
        checkFile[i].send();
        }
    }
}
if (existing.indexOf(true) == -1) {
    //none of the files to be uploaded are already on server
    //this _always_ was fired - even when there are files with the same name on the server!!!??
    return true; 
}
else {
    //list filenames and/or upload field numbers of the files that already exist on server
    return false;
   }
}

我的思维错误了吗?或者我的代码中有一些简单的错误?我有什么想法可以归档我的目标吗?

2 个答案:

答案 0 :(得分:0)

我发现您的代码存在两个潜在问题。

第一个是same origin policy:如果upload_path与当前页面不在同一个域中,则请求可能会失败。

第二个是你的索引:当我增加时,当你alert(existing[i])时,我已经等于fields.length。你需要创建一个闭包:

for (var i = 0; i < fields.length; i++) {
    (function(index){
    // use index within your code
    })(i); // the loop will execute with index=i
}

答案 1 :(得分:0)

好的,我找到了答案 - 以防万一有人感兴趣......

除了Christophes注意到必须创建循环的闭包之外,当然也必须在该循环函数内部检查数组,否则立即检查(即没有单个响应时)还没有检查XMLHttpRequests,因为它只检查过一次,它总是负数。 除此之外,我们必须确保在检查数组中的值之前完成所有请求(而不仅仅是处理)。我们通过将填充的上载字段数与已设置到字符串中的值的数量(在相应请求的readystate-response返回之后发生)进行比较来实现。 代码中有更多解释。

干杯,克里斯

function NoOverwrite() {
var fields = document.querySelectorAll("input[type=file]");
var existing = new Array();
var checkFile = new Array();
var file = new Array();
var fileUrl = new Array();
var counter = 0;
for (var i = 0; i < fields.length; i++) {
    (function(index){
        file[index] = document.getElementById('file'+i).files[0];
        if(file[index]) {
            fileUrl[index] = 'upload_path/' + file[index].name;
            checkFile[index] = new XMLHttpRequest();
            checkFile[index].onreadystatechange = function() {
                if (checkFile[index].readyState == 4) {
                    if (checkFile[index].status == 200) {
                        existing[index] = true; 
                        counter += 1;
                    }
                    else {
                        existing[index] = false;
                        counter += 1;
                    }
                    if (counter == fileUrl.length) { 
                            //existing.length of the array "true, false,,true" (i.e. with one undefined value) would deliver "4". 
                            //therefore we have to check for the number of set variables in the string rather than the strings length. 
                            //we use a counter for that purpose. everything after this point is only executed when the last file has been checked! 
                        if (existing.indexOf(true) == -1) {
                            //none of the files to be uploaded are already on server
                            return true; 
                        }
                        else {
                            //list filenames and/or upload field numbers of the files that already exist on server
                            //   ->> inform user... 
                            return false;
                        }
                    }
                }
            }
            checkFile[index].open('HEAD', fileUrl[index], true);
            checkFile[index].send();
        }
    })(i);
}
}