一時間ほどハマってしまいました。
やりたかったこと
S3+Cloudfrontでホスティングしている静的サイトに拡張子なしでテキストファイルを置きたかった。
問題
S3のファイルのメタデータのContent-Type: text/plain
を設定してもブラウザ側でバイナリファイルと判断されダウンロードが始まってしまう。
結論
BOMがなかった。BOMを追加する。
まずはBOMの確認方法。
$ file hoge.txt
hoge.txt: ASCII text # BOMがないときの表示
$ file hoge.txt
hoge.txt: UTF-8 Unicode (with BOM) text # BOMがあるときの表示
BOMを追加。
$ nkf --overwrite --oc=UTF-8-BOM hoge.txt
hoge.txt: UTF-8 Unicode (with BOM) text
あとはS3にアップロードするだけです。
余談ですが間違って追加したBOMの削除は
$ nkf --overwrite --oc=UTF-8 hoge.txt
hoge.txt: ASCII text
でできます。
原因
ブラウザによるSniffingが行われてContent-Type
をtext/plain
に設定してもバイナリファイルと判断されてしまっていた。
Sniffingをさせない方法としては
-
X-Content-Type-Options : nosniff
をHTTPヘッダに設定してSniffingさせない。- .htaccessでHTTPヘッダに追加。
- S3では.htaccessは使えない。
- S3のメタデータでHTTPヘッダに追加。
-
X-Content-Type-Options
メタデータは提供されていない。
-
- Lambda@Edgeの
Viewer Response
でHTTPヘッダに追加。- お金かかるしオーバヘッドになるのでやりたくない。
- .htaccessでHTTPヘッダに追加。
-
Sniffingしたときにtxtファイルと判断させる。
- BOMを追加すればよい!!!
という行程でした。
余談ですが、X-robot-tag: noindex
をヘッダに追加したい場合はhtmlファイルでない限り、Lambda@Edgeでヘッダーを追加するしかなさそう。
.htaccessが使えなかったり不便な点もありますが、メンテ無しで料金も安いS3のホスティングは素晴らしい〜!!
参考
追記