2023年4月12日水曜日

Chrome を使ったフォルダ走査

2023-04 現在、Chromium系のブラウザは、ドロップされたフォルダに対する走査が実現可能であり、 再帰的にフォルダを走査することで、配下も含めたフォルダやファイルが制御可能なため、 フォルダ配下のファイルをまとめてアップロードすることもできる。

つまり、サーバ側のAPIを整えフォルダまで扱える機能がサーバ側に備わっていれば、 フォルダ階層も含めてファイルをアップロードできるのである。

ただし、これが実行できる状況には制限があり、サーバとの接続が localhost か https 環境のみ、 いわゆるセキュリティ的に問題のない経路でしか動作しない。

特にイントラ内での開発やテストにおいて、192.168.*.* 等に http で接続して動かない。 というパターンで動かない。という状況に陥る人が多いため注意すること。

で、今回はドロップされたフォルダを再帰的に走査する JavaScript を書いてみようと思う。

以下に HTML 一式を示す。ローカルのウェブサーバに置けば確認できるはずだ。

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <title>ドロップされたフォルダの走査</title>
  <style>
    #drop-area {
      width: 100%;
      height: 200px;
      border: 2px dashed #ccc;
      text-align: center;
      line-height: 200px;
    }
  </style>
</head>
<body>
  <div id="drop-area">フォルダをここにドロップ</div>
  <ul id="file-list"></ul>
  <script>
    function handleFolder(folder) {
      const reader = folder.createReader();
      reader.readEntries(function (entries) {
        entries.forEach(function (entry) {
          if (entry.isDirectory) {
            handleFolder(entry);
          } else if (entry.isFile) {
            const listItem = document.createElement('li');
            listItem.textContent = entry.fullPath;
            document.getElementById('file-list').appendChild(listItem);
          }
        });
      });
    }

    document.getElementById('drop-area').addEventListener('dragover', function (event) {
      event.preventDefault();
    });

    document.getElementById('drop-area').addEventListener('drop', function (event) {
      event.preventDefault();
      const items = event.dataTransfer.items;
      for (let i = 0; i < items.length; i++) {
        const item = items[i];
        if (item.kind === 'file' && item.webkitGetAsEntry().isDirectory) {
          handleFolder(item.webkitGetAsEntry());
        }
      }
    });
  </script>
</body>
</html>

Chromium系ブラウザでは、webkitGetAsEntry() メソッドを使って、ファイルアイテムからディレクトリエントリを取得できるため、 フォルダである場合はフォルダ走査を行う handleFolder関数を呼び出している。

handleFolder関数は、渡されたフォルダを走査し、ディレクトリだった場合は再帰的に走査し、ファイルだった場合はファイルパスを ul要素に追加している。

実際のプロジェクトで使うには、複数ドロップされた場合やドロップ後のアップロード処理、エラー処理など様々な処理が必要となるため、 非常に複雑なものとなってしまうが、基本的なフォルダ走査を行う要素は上記のように再帰的な処理で捉えてしまえば単純なものとなる。


0 件のコメント:

コメントを投稿