作った機能
今回フロント側を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つあるなど)
      
      
      
      
  
  
  
  

コメント