Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
258 views
in Technique[技术] by (71.8m points)

html - Uploading directory and maintainign structure through JavaScript and HTML5

I'm trying to upload whole folders through the browser. I've done a fair bit of tinkering today and discovered that there are a number of great solutions for uploading folders. However, when testing them, they seem to be making the list of files in the folders ready for upload, sans directory structure.

Is there any recommended tool I can use to drag and drop, or even just select and upload, entire folders from my site (and of course, maintain structure)?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Not really officially yet, but there will probably be, available for us mere web-developers* through the Files and Directory API which specs are still in the process of being written, even though chrome and Firefox already implement something similar through a webkit-API*, which allows us to access and navigate dropped directories.

So if we try to use this webkit-API, we could write something like this:

/* constructs a simple directory view from a filesystem */
async function makedir(entries) {

  const systems = entries.map(entry => traverse(entry, {}));
  return Promise.all(systems);

  async function traverse(entry, fs) {
    if (entry.isDirectory) {
      fs[entry.name] = {};
      let dirReader = entry.createReader();
      await new Promise((res, rej) => {
        dirReader.readEntries(async entries => {
          for (let e of entries) {
            await traverse(e, fs[entry.name]);
          }
          res();
        }, rej);
      });
    } else if (entry.isFile) {
      await new Promise((res, rej) => {
        entry.file(file => {
          fs[entry.name] = file;
          res();
        }, rej);
      });
    }
    return fs;
  }
}

function readDropped(dT) {
  const entries = [...dT.items].map(item => {
      return item.webkitGetAsEntry ? item.webkitGetAsEntry() : null;
    })
    .filter(entry => entry);
  if (entries.length) {
    makedir(entries)
      .then(output)
      .catch(handleSecurityLimitation);
  } else notadir();

}

function notadir() {
  _log.textContent = "wasn't a directory, or webkitdirectory is not supported";
}

dropzone.ondragover = e => {
  e.preventDefault();
  dropzone.classList.add('over');
}
dropzone.ondragexit = dropzone.ondragend = e => dropzone.classList.remove('over');
dropzone.ondrop = e => {
  e.preventDefault();
  dropzone.classList.remove('over');
  readDropped(e.dataTransfer);
}

function output(system_trees) {
  console.log(system_trees);
  _log.textContent = JSON.stringify(system_trees, checkFile, 2);

  function checkFile(key, value) {
    if (value instanceof File) {
      return '{[File] ' + value.name + ', ' + value.size + 'b}';
    } else return value;
  }
}

function handleSecurityLimitation(error) {
  console.error(error);
  document.body.innerHTML = `
    <h2>Faced security limitations</h2>
    <a href="https://jsfiddle.net/x85vtnef/">Please go to this fiddle</a>`;
}
#dropzone {
  border: 1px solid;
  width: 90vw;
  height: 90vh;
  margin: 2vmin;
  padding: 2vmin;
  overflow: auto;
}

#dropzone.over {
  background-color: rgba(0, 0, 0, .2);
}
<div id="dropzone">
  Drop some directory here.
  <pre id="_log"></pre>
</div>

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...