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