web-dev-qa-db-ja.com

Nginx:URIによるContent-Typeの設定問題

私は小さな個人ファイルホスティングを設定しています。アップロードされたファイルを/f/ab/cd/ef012345678...のようなHDDに直接ハッシュで保存するバックエンドを作成しましたが、ファイル拡張子なしでexample.com/f/ab/cd/ef012345678.../filename.jpgのようなURIを生成します。

Nginxは、この設定を使用してHDDからファイルを直接提供します。

location /f {
     rewrite "^/f/([a-z0-9]+)/([a-z0-9]+)/([a-z0-9]+)(.*)$" /$1/$2/$3 break;
     root /srv/cdn/f;
}

つまりURIの最後の部分を切り取り、ハッシュのみを使用してファイルを読み取ります。うまく機能しますが、ファイルのMIMEタイプをapplication/octet-streamにストリップします。これにより、ブラウザーはすべてのファイルをダウンロードしますが、インラインで画像を表示します。

この場所に次のような設定を含めることで回避策を作成しました。

if ($request_uri ~* \.png$) {
    add_header Content-Type "image/png";
}

これにより、Google ChromeおよびFirefoxの最初のロードの問題が修正されます。

しかし、Firefoxで2回目にリンクを開くか、単にページをリロードすると、ダウンロードするように求められます。どうやら、Firefoxは304応答のContent-Typeをうまく処理していません(ヘッダーをチェックし、ファイルがキャッシュからプルされた場合、Nginxはこの構成で304応答とContent-Typeヘッダーを送信します)。

Nginx configでファイルがキャッシュのサーバーであるかどうかを判断し、ヘッダーを追加しない方法を探していますNginx解決策。

私はバックエンドを変更してファイル拡張子を追加することをお勧めします、それはいくつかの将来の問題も解決しますが、今私は眠ることができず、Nginxを使用して答えを知る必要があります

3
Eirenliel

なぜこのメソッドが機能し、rewrite...breakメソッドが機能しないのかはわかりません。ただし、locationステートメントで正規表現をキャプチャし、alias式で使用すると、元のリクエストURIに従ってContent-Typeを残すように見えます。

例えば:

location ~ ^/(f/[a-z0-9]+/[a-z0-9]+/[a-z0-9]+) {
    alias /srv/cdn/$1;
}

詳しくは このドキュメント をご覧ください。

正規表現locationステートメントは順序付けられているため、構成ファイル内での位置が重要になる場合があることに注意してください。詳しくは このドキュメント をご覧ください。

0
Richard Smith