2016-09-06 3 views
2

AJAX를 통해 d' n'd하여 서버에 폴더를 업로드하고 싶습니다. 하지만 이미 업로드 파일에 문제가 있습니다.어떻게 Ajax를 통해 파일을 전송할 수 있습니까?

나는 파일이나 폴더를 확인하기 위해 e.dataTransfer.itemswebkitGetAsEntry()을 사용합니까?

파일 인 경우 기능이 traverseFileTree인데 파일이 있지만 formData에 추가 할 수 없습니다.

e.dataTransfer.files을 사용하는 경우 무엇인지 알 수 없습니다. webkitGetAsEntry() 오류가 발생하여 파일 또는 폴더.

내가 뭘 잘못 했니? 전역 배열 $ _FILES로 파일을 전송하는 방법.

소스 (upload.php로) :

echo "<pre>"; 
print_r ($_FILES); 
echo "</pre>"; 

소스 (index.html을) :

<!DOCTYPE html> 
<html> 
<head> 
<title>Drag and Drop</title> 
<style> 
body { 
    background: rgba(211,211,100, .5); 
    font: 20px Arial; 
} 

.dropzone { 
    width: 300px; 
    height: 300px; 
    border: 2px dashed #aaa; 
    color: #aaa; 
    line-height: 280px; 
    text-align: center; 
    position: absolute; 
    left: 50%; 
    margin-left: -150px; 
    top: 50%; 
    margin-top: -150px; 
} 

.dropzone.dragover { 
    color: green; 
    border: 2px dashed #000; 
} 
</style> 
</head> 
<body> 
<p>Loaded files:</p> 
<div id="uploads"> 
    <ul> 

    </ul> 
</div> 
<div class="dropzone" id="dropzone">Drop files</div> 
<script> 

(function() { 
    var formData = new FormData(); 
    var dropzone = document.getElementById("dropzone"); 

    dropzone.ondrop = function(e) { 
     this.className = 'dropzone'; 
     this.innerHTML = 'Drop files'; 
     e.preventDefault(); 
     upload(e.dataTransfer.items); 
    }; 

    function traverseFileTree(item, path) { 
     path = path || ""; 
     if (item.isFile) { 
      item.file(function(file) { 
       console.log(file);     // show info 
       formData.append('file[]', file); // file exist, but don't append 
      }); 
     } /*else if (item.isDirectory) { 
      var dirReader = item.createReader(); 
      dirReader.readEntries(function(entries) { 
       for (var i=0; i<entries.length; i++) { 
        traverseFileTree(entries[i], path + item.name + "/"); 
       } 
      }); 
     }*/ 
    } 


    var upload = function(items) { 
     var xhr = new XMLHttpRequest(); 

     for(var i = 0; i < items.length; i++) { 
      var item = items[i].webkitGetAsEntry(); 
      if (item) { 
       traverseFileTree(item,''); 
      } 
     } 

     xhr.onload = function() { 
      console.log(this.responseText); 
     }; 

     xhr.open('post', 'upload.php'); 
     xhr.send(formData); 
    }; 

    dropzone.ondragover = function() { 
     this.className = 'dropzone dragover'; 
     this.innerHTML = 'Mouse up'; 
     return false; 
    }; 

    dropzone.ondragleave = function() { 
     this.className = 'dropzone'; 
     this.innerHTML = 'Drop files'; 
     return false; 
    }; 

})(); 
</script> 

+0

그래서, 당신은이 크롬 및 기타 웹킷 기반 브라우저에서 작동하고 싶어? –

+0

@JaromandaX firefox는 폴더 업로드를 지원합니다. [파일 선택 및/또는 파싱 할 폴더 선택] (http://stackoverflow.com/questions/36842425/select-drop-files-and-or-folders-to-be) -parsed /) – guest271314

+0

@JaromandaX 네, 크롬에서 작동하길 원합니다 .... 나는 상관하지 않습니다. 나는 단지 그것이 일하기를 바란다. 나는 언젠가 그것을 해결할 수 없다. 나는 dropBox와 같은 일을하고 싶습니다. 사용자가 폴더를 드롭 할 수 있습니다. –

답변

1

모두 file()readEntries() 반환 결과 비동기. 더 많은 파일이나 폴더를 포함하는 추가 디렉토리가 포함될 수있는 파일이나 디렉토리의 수를 사용자가 선택하여 삭제할 수 있는지 여부를 알 수 없으므로 traverseFileTree에 대한 단일 호출 또는 재귀 호출은 비동기 작업이 완료되었습니다. 이는 여러 가지 방법 중 하나 이상을 사용하여 수행 할 수 있습니다.

이 접근법은 변수 n을 증가시키고, 각각의 개별 파일을 배열 uploads에 푸시 (push)한다. n0 인 경우 첫 번째 파일을 처리하십시오. 그 값이 배열 .length까지 파일 .length 함유 어레이보다 1n - 1 같도록 processFiles 기능하도록 파일의 배열을 통과

uploads.length === n - 1 || n === 0 

후, .slice()를 사용 uploads 배열 복사 0uploads.lengthn 설정 n 증분 파일에 FormData() 개체가 추가 된 경우 XMLHttpRequest()으로 전화가 걸립니다.

<!DOCTYPE html> 
<html> 

<head> 
    <title>Drag and Drop</title> 
    <style> 
    body { 
     background: rgba(211, 211, 100, .5); 
     font: 20px Arial; 
    } 

    .dropzone { 
     width: 300px; 
     height: 300px; 
     border: 2px dashed #aaa; 
     color: #aaa; 
     line-height: 280px; 
     text-align: center; 
     position: absolute; 
     left: 50%; 
     margin-left: -150px; 
     top: 50%; 
     margin-top: -150px; 
    } 

    .dropzone.dragover { 
     color: green; 
     border: 2px dashed #000; 
    } 
    </style> 
</head> 

<body> 
    <p>Loaded files:</p> 
    <div id="uploads"> 
    <ul> 

    </ul> 
    </div> 
    <div class="dropzone" id="dropzone">Drop files</div> 
    <script> 
    (function() { 
     var n = 0, uploads = []; 

     var dropzone = document.getElementById("dropzone"); 

     dropzone.ondrop = function(e) { 
     this.className = 'dropzone'; 
     this.innerHTML = 'Drop files'; 
     e.preventDefault(); 
     upload(e.dataTransfer.items); 

     }; 

     function processFiles(files) { 
     console.log("files:", files); 
     alert("processing " + files.length + " files"); 
     var formData = new FormData(); 
     // append files to `formData` 
     for (file of files) { 
      formData.append("file[]", file, file.name) 
     } 
     // check `formData` entries 
     var curr = 0; 
     for (data of formData.entries()) { 
      console.log("formData entry " + curr, data); 
      ++curr; 
     } 
     delete curr; 
     // do ajax stuff here 
     var xhr = new XMLHttpRequest(); 
     xhr.onload = function() { 
     console.log(this.responseText); 
     }; 

     xhr.open("POST", "upload.php"); 
     xhr.send(formData); 
     } 

     function traverseFileTree(item, path) { 

     var handleFiles = function handleFiles(item, path) { 
      path = path || ""; 
      if (item.isFile) { 
      item.file(function(file) { 
       uploads.push(file); 
       console.log(file, n, uploads.length); // show info 
       if (uploads.length === n - 1 || n === 0) { 
       alert("traverseFiles complete, uploads length: " 
         + uploads.length); 
       var files = uploads.slice(0); 
       n = uploads.length = 0; 
       processFiles(files) 
       } 
      }); 
      } else if (item.isDirectory) { 
      var dirReader = item.createReader(); 
      dirReader.readEntries(function(entries) { 
       // increment `n` here 
       n += entries.length; 
       for (var i = 0; i < entries.length; i++) { 
       handleFiles(entries[i], path + item.name + "/"); 
       } 
      }); 
      } 
     } 

     handleFiles(item, path); 

     } 

     var upload = function(items) { 

     if (n !== 0 && uploads.length !== 0) { 
      n = uploads.length = 0; 
     } 

     for (var i = 0; i < items.length; i++) { 
      var item = items[i].webkitGetAsEntry(); 
      if (item) { 
      traverseFileTree(item, ""); 
      } 
     } 

     }; 

     dropzone.ondragover = function() { 
     this.className = 'dropzone dragover'; 
     this.innerHTML = 'Mouse up'; 
     return false; 
     }; 

     dropzone.ondragleave = function() { 
     this.className = 'dropzone'; 
     this.innerHTML = 'Drop files'; 
     return false; 
     }; 

    })(); 
    </script> 
</body> 
</html> 

plnkr http://plnkr.co/edit/OdFrwYH2gmbtvHfq3ZjH?p=preview


또한보십시오 How can I filter out directories from upload handler in Firefox?, How to read files from folder

+1

대단히 감사합니다! 유용하고 유용합니다. 그러나 명확하지 않은 점이 있습니다. 어쩌면 결국 나는 그 이유를 이해합니다. 죄송합니다. 오랫동안 대답하지 않으 셨으며 상세한 답변을 주셔서 감사합니다! 약간 변경된 코드는 다음과 같습니다. [codepen.io] (http://codepen.io/work_forfood/pen/bwVWXL) –

관련 문제