【react】ブラウザで作成したhtmlをS3にアップする機能作った

react

※プロモーションページが含まれる場合があります

作った機能

今回フロント側をreact、サーバ側をnodeでアプリを作成したが、S3にアップロードの作業はすべてreact側で実装。aws-sdkを使用。自身の備忘録として記述。

s3にアップしているものを一覧表示できる

データの中身は見せれないけどこんな感じで一覧表示できる。

s3のファイルの取り方(listObjectsV2で取得できる)
const s3 = new AWS.S3({
  accessKeyId: REACT_APP_S3_ID,
  secretAccessKey: REACT_APP_S3_SECRET_KEY,
}); 
 
 /**
   * アップロードリスト取得
   *
   * @param {string} prefix ディレクトリパス
   * @return {object} ファイルリスト
   */
  const list = async (prefix) => {
    const params = {
      Bucket: REACT_APP_S3_BUCKET_NAME,
    };
    s3.config.update({ region: REACT_APP_S3_REGION });
    if (prefix) params.Prefix = prefix;
    const res = await s3.listObjectsV2(params).promise();
    return res;
  },

`listObjectsV2` という関数でファイル一覧を取得できる。

prefixをparamsに追加することでフォルダの絞り込みができる。

任意のデータを編集できる(↑赤丸押したあと)

選んだデータをそのまま編集できるようにする

やり方(fetchで指定したurlのhtml構造を取得)
    const url = `${REACT_APP_S3_URL}/${fileName}.html`;  // アップロードしたurlを指定
    const targetHtml = await fetch(url, {
      method: Method.GET,
    })
      .then((response) => response.text())
      .then((text) => {
        return text;     // textに指定したファイルのhtml構造が入る
      });

    return targetHtml;

// 初期値が↓の構造なのでbodyタグのみにする
  const HTML = `<!doctype html>
  <html>
    <head>
      <meta charset="utf-8">
      <title>playground</title>
    </head>
    <body>
      ${val}
    </body>
  </html>
  `;

// bodyタグの中身だけにする
const getEditHtmlBody = (editData) => {
  if (!editData) return;
  const startStr = editData.indexOf('<body>') + '<body>'.length;
  // 文字位置取得
  const endStr = editData.indexOf('</body>'); // 文字位置取得
  const result = editData.substring(startStr, endStr); // substringで指定した文字の間の文字を取得できる。
  return result.trim();  // trim()で空白を削除
};

s3にアップロードしている画像一覧を表示できる

やり方
// imgタグ生成
const getImgTags = (link) => {
  return (
    <>
      <img src={`${s3URL}/${link}`} style={{ width: 100, height: 100 }}></img>
    </>
  );
};

// S3にアップロードされている画像データを取得
const getImgList = async (info) => {
  const res = await s3Action.list(info);
  const img = [];
  for (const content of res.Contents) {
    if (content.Key.split('.').pop() === 'html') continue;   // 拡張子が画像の物だけを抽出
    img.push({
      imgLink: content.Key,
      image: getImgTags(content.Key),
    });
  }
  return img;
};

s3に画像をアップロードできる

やり方(uploadでs3上にアップロードできる)
  // 画像アップロード
  const imgUpHandleClickOk = useCallback(async () => {
    const image = ref.current.files[0];  // useRefを使ってる
    const fileName = `${s3URL}/${image.name}`;
    await upload(image, fileName);
  }, []);


  const upload = async (file, fileName) => {
    const params = {
      Bucket: REACT_APP_S3_BUCKET_NAME,
    };
    if (!file) return;
    s3.config.update({ region: REACT_APP_S3_REGION });
    if (fileName.split('.').pop() === Extension.HTML) params.ContentType = ContentType.TEXT_HTML;
    params.Key = fileName; // s3へ保存される名前 ユニーク必須
    params.Body = file;
    await s3.upload(params, function (err, data) {
      if (err) {
        throw err;
      }
      console.log(`File uploaded successfully. ${data.Location}`);
    });
  },

作成したhtmlをS3にアップロードできる

やり方

// ↑の画像のパターンと拡張子が違うだけ。
// 注意: contentTypeをtext/htmlに指定する
  upload: async (file, fileName) => {
    const params = {
      Bucket: REACT_APP_S3_BUCKET_NAME,
    };
    if (!file) return;
    s3.config.update({ region: REACT_APP_S3_REGION });
    if (fileName.split('.').pop() === Extension.HTML) params.ContentType = ContentType.TEXT_HTML;
    params.Key = fileName; // s3へ保存される名前 ユニーク必須
    params.Body = file;
    await s3.upload(params, function (err, data) {
      if (err) {
        throw err;
      }
      console.log(`File uploaded successfully. ${data.Location}`);
    });
  },

今回の実装で詰まったところ

やり始めたころはs3なんて全くわかってなかった。しかも社内のインフラ担当が別にいるのでawsの中身は自分ではみることができないのでイメージが全然できなかった。

aws-sdkをつかってのアップロード、アップロード確認などでてこずった。(サイバーダックで見ることができた)

urlがあっているのかわからず・・

配布されたurlが~.comと`.net`の二つがあってどれを使うかわからず。初めは違いに気づかず。。

全然webに表示されないから署名付きurlとかその辺の話まで手を突っ込んでしまった。

正解は`.net`をつかう。

アップロードしたものが表示されずにダウンロードされる

htmlファイルをアップロードしたが、それをurlを叩いてもweb上で表示されずにダウンロードされる。

解決方法

アップロードしたファイルがcontetTypeがtext/htmlになってなかった。

アップロードしたファイルのhtml構造がおかしかった。アップロードする前に確認するとhtmlの構造が崩れてた(bodyタグが2つあるなど)

コメント

タイトルとURLをコピーしました