0

このスクリプトのアイデアの何が問題なのかを見つけることができないようで、機能させることができません。多分あなたは私を助けることができます、それは非常に高く評価されます.

複数ファイルのアップロードフォームに取り組んでいます。アップロードする前に (それ以前ではありません)、いくつかのファイルが既にアップロード ディレクトリに存在するかどうか (存在する場合はどのファイルか) を確認したいと考えています。そのために 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;
   }
}

私は私の考えに誤りを犯しましたか?または、私のコードにいくつかの単純な間違いがありますか? 目標をアーカイブする方法はありますか?

4

2 に答える 2

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);
}
} 
于 2012-12-04T01:15:36.153 に答える
0

あなたのコードには 2 つの潜在的な問題があります。

1 つ目は同一オリジン ポリシーです。upload_path が現在のページと同じドメインにない場合、リクエストは失敗する可能性があります。

2 番目はインデックスです。i が増加すると、alert(existing[i])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
}
于 2012-12-03T16:39:28.853 に答える