web-dev-qa-db-ja.com

小さなnginxドキュメント本体を提供するNGINX301および302。この動作を削除する方法はありますか?

Nginxの内部301および302処理を使用する場合、nginxは適切なLocation:...ヘッダーを持つ小さなドキュメント本文を提供することに気づきました。

(htmlで)の線に沿った何か:301リダイレクト-nginx。

上記の動作に応じて、content-type text/htmlおよびcontent-lengthヘッダーも送信されます。

私たちは多くの302といくつかの301リダイレクトを実行しますが、上記の動作は私たちの意見では帯域幅を浪費しています。

この動作を無効にする方法はありますか?

私たちの頭に浮かんだアイデアの1つは、error_page 301302を空のテキストファイルに設定することでした。これはまだテストしていませんが、上記でも、content-typeヘッダーとcontent-length(0)ヘッダーが送信されると想定しています。

それで、nginxで「ボディレス」301/302リダイレクトを送信するクリーンな方法はありますか?

6
anonymous-one

あなたが何を求めているのかを非常に注意深く考え、それをしないことを強く検討してください

RFC 2616 削除するエンティティ本体が存在する必要があることを指定します。

10.3.2 301を永続的に移動

新しい永続的なURIは、応答のLocationフィールドで指定する必要があります。リクエストメソッドがHEADでない限り、レスポンスのエンティティには、新しいURIへのハイパーリンクを含む短いハイパーテキストノートを含める必要があります(SHOULD)。

そして...

10.3.3 302が見つかりました

一時的なURIは、応答のLocationフィールドで指定する必要があります。リクエストメソッドがHEADでない限り、レスポンスのエンティティには、新しいURIへのハイパーリンクを含む短いハイパーテキストメモが含まれている必要があります。

この文脈では、SHOULDは RFC 2119 で定義されています。

この単語、または形容詞「RECOMMENDED」は、特定の状況で特定の項目を無視する正当な理由が存在する可能性があることを意味しますが、別のコースを選択する前に、完全な意味を理解し、慎重に検討する必要があります。

これで、RFCに違反することなくこれを行うことができますが、完全な影響に注意する必要があります。

  • あなたは事実上何の利益もなく多くの仕事をしています。エンティティ本体を無効にすることを考えることができる唯一の論理的な理由は、帯域幅のコストを節約することです。実際、これがあなたが言及した理由ですが、違いはごくわずかであるため、帯域幅のグラフに違いが見られることはほとんどありません。
  • Webクライアントのごく一部は、自動的に3xxリダイレクトに従いません。 RFCが書かれたとき、この割合ははるかに大きかったので、そもそもこれがそこにありますが、暗い寝室とデータセンタークローゼットの影に潜んでいる古代の怪物がまだあり、時々彼らは遊びに出ます。最もよく見られるのはcurlで、これはまだ一般的に使用されています。

この推奨は RFC 7231 で多少緩和されています。これは単に(301と302の両方に対して)次のように述べています。

通常、サーバーの応答ペイロードには、新しいURIへのハイパーリンクを含む短いハイパーテキストノートが含まれています。

サーバーの応答ペイロードには通常、さまざまなURIへのハイパーリンクを含む短いハイパーテキストメモが含まれています。

9
Michael Hampton

はい、[〜#〜]絶対に[〜#〜]NGINXで実行できます!

  • 例外ハンドラa.k.a. error_page をインストールするだけで、必要な応答を後処理できます。エラーページがHTTPステータスコードを変更しないように設定してください。たとえば、=パラメータを使用しないでください(または、必要なコードをハードコーディングするために使用してください)。

  • 必ず returnURLではなく[text]をオプションで設定できる戻りステータスコードを含む応答を確認してください。

  • default_typeの-​​ "" を指定します。これにより、Content-Typeヘッダーが削除されます。

完全なコードは次のとおりです。これも StackOverflow.cnst.nginx.conf リポジトリの GitHub にあります。

# cat sf.421976.301-302-redirect-w-no-http-body-text.nginx.conf | sed 's#^#\t#g'
server {
    listen 1976;
    error_page 301 302 @30x; # keep original HTTP status code w/o `=`
    location @30x {
        default_type ""; # will remove Content-Type completely
        # `300` is a filler: client will get the original HTTP status code
        return 300;
    }
    return 301 http://example.su/test;
}

正しく機能していることの確認は次のとおりです。

% curl -i localhost:1976 | sed 's#^#\t#g'
HTTP/1.1 301 Moved Permanently
Server: nginx/1.2.1
Date: Mon, 28 Aug 2017 22:02:41 GMT
Content-Length: 0
Connection: keep-alive
Location: http://example.su/test

%

私はブラウザで試してみましたが、そこでもうまくいきました。

P.S.別のオプションは、ソースコードを変更して ngx_http_error_301_page et al変数を編集することですが、なぜハードルートを選択するのですか? ^ _ ^

6
cnst

少し見苦しいですが、おそらく301/302リクエストをプロキシし、proxy_methodを使用してGETをHEADリクエストに変更できます。私はテストしていませんが、headリクエストは応答なしでヘッダーのみを送信する必要がありますまたは(うまくいけば)content- *ヘッダー。

http://wiki.nginx.org/NginxHttpProxyModule#proxy_method

0
blueben