🏋️

http-serverからゴリ押しでディレクトリ情報を持ってくる

2022/10/07に公開

やりたいこと

フロントエンドからhttp-server上にあるディレクトリ一覧を出したい

調べる

  • http-serverにはHTTPからファイル情報を引っ張れるAPIとかそういうのは多分無いっぽい
  • http-serverの中身はなるべく弄りたくない
  • http-serverが返すHTMLの中身はシンプル
    • もうHTMLをfetchしてそこから抜き出すのがお手軽そう

やってみる

前提

http-serverを起動する時に-cors引数を入れておく

  • 多分こういう使い方を想定していると思われる。ありがとうhttp-server。

実装

export interface DirectoryItem {
  name: string
  type: "directory" | "file"
  perms: string
  lastModified: string
  fileSize?: string
}

export const getDirs = async (path = ""): Promise<Array<DirectoryItem>> => {
  let resDirs = [] as Array<DirectoryItem>;

  const res = await fetch("http://xxx.xxx.xxx.xxx:yyyyy/" + path);
  const resHTML = new DOMParser().parseFromString(await res.text(), "text/html");

  const perms = resHTML.getElementsByClassName("perms"); // パーミッション
  const lastModified = resHTML.getElementsByClassName("last-modified"); // 最終更新日
  const fileSize = resHTML.getElementsByClassName("file-size"); // ファイルサイズ
  const displayName = resHTML.getElementsByClassName("display-name"); // ファイル名
  
    for (let i = 0; i < perms.length; i++) {
    resDirs.push({
      name: displayName.item(i)!.firstElementChild!.innerHTML,
      perms: perms.item(i)!.firstElementChild!.innerHTML,
      lastModified: lastModified.item(i)!.innerHTML,
      fileSize: fileSize.item(i)!.firstElementChild?.innerHTML,
      type: (fileSize.item(i)!.firstElementChild?.innerHTML) ? "file" : "directory"
    });
  }

  return resDirs;
}

注意点など

  • getElementsByClassNameで帰ってくるのはHTMLCollectionなのでforEach等が使えない
  • ファイル・ディレクトリの判別はファイルサイズの文字列が空かどうかで判断している

おまけメモ

../に移動したい時の正規表現:/\/[^\/]*$/

Discussion