我似乎找不到这个脚本的想法有什么问题,也不能让它工作。也许你能帮我,我将不胜感激。
我正在写一个多文件上传表。在上传之前(而不是在此之前),我想检查一些文件(如果存在,哪些文件)已经存在于上传目录中。我正在使用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;
}
}我的思维有没有错?或者我的代码中有一些简单的错误?你知道我该如何实现我的目标吗?
发布于 2012-12-04 09:15:36
好吧,我找到答案了--如果有人感兴趣的话……
除了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-04 00:39:29
我发现你的代码中有两个潜在的问题。
第一个是same origin policy:如果upload_path与当前页面不在同一个域中,则请求可能会失败。
第二个是你的索引:随着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
}https://stackoverflow.com/questions/13687499
复制相似问题