📌
[小ネタ]S3にhtmlファイルをboto3でアップロードして失敗していた話
さきにまとめ
sdkでhtmlファイルをS3バケットにアップロードするときは、ContentType='text/html'
を指定しましょう。
やりたかったこと
- S3で静的ファイルをホストしたい
- boto3でhtmlファイルをアップロードしたい
失敗の状態
- ファイルのURLにアクセスして表示しようとすると、htmlファイルをダウンロードしてしまう
- ダウンロードしたファイルはローカルからは正常に開ける
原因
無指定で、Content-Type
が binary/octet-stream
になっていた。
text/html
が正しい。
コード
パターン別に書いています。
前提
- bucketがある
- htmlファイルをアップロードしたい
- コード内でhtmlを作る場合
- htmlファイルがすでにある場合
import boto3
html_content = """<!DOCTYPE html>
<html>
<head>
<title>Hello world!</title>
</head>
<body>
<h1>Hello world!</h1>
</body>
</html>
"""
bucket = "my−static-bucket"
html = "test-my-file.html"
# html_contentを使うとき その1
client = boto3.client("s3")
client.put_object(Body=html_content, Bucket=bucket, Key=html, ContentType="text/html")
# html_contentを使うとき その2
s3 = boto3.resource("s3")
s3.Object(bucket, html).put(Body=html_content, ContentType="text/html")
# ファイルがすでにあるとき その1
client = boto3.client("s3")
client.upload_file("upload.html", bucket, html, ExtraArgs={"ContentType": "text/html"})
# ファイルがすでにあるとき その2
s3 = boto3.resource("s3")
s3.meta.client.upload_file(
"upload.html", bucket, html, ExtraArgs={"ContentType": "text/html"}
)
まとめ
- 何も指定せずにhtmlファイルをboto3でアップロードすると
binary/octet-stream
になってしまうので、明示的にContentType="text/html"
を指定します - 書き方がいろいろあるのは迷いますね
参考にしたもの
--
ChatGTP(3)に聞いても正しく答えてくれました。
コードはこちら。
import boto3
s3_client = boto3.client('s3')
s3_client.upload_file('path/to/local/file.html', 'my-bucket', 'test.html', ExtraArgs={'ContentType': 'text/html'})
Discussion