web-dev-qa-db-ja.com

Flask 301応答

私のflaskアプリは、URLの1つに対して301リダイレクトを実行しています。

New Relicのトレースバックは次のとおりです。

Traceback (most recent call last):
  File "/var/www/app/env/local/lib/python2.7/site-packages/flask/app.py", line 1358, in full_dispatch_request
    rv = self.dispatch_request()
  File "/var/www/app/env/local/lib/python2.7/site-packages/flask/app.py", line 1336, in dispatch_request
    self.raise_routing_exception(req)
  File "/var/www/app/env/local/lib/python2.7/site-packages/flask/app.py", line 1319, in raise_routing_exception
    raise request.routing_exception
RequestRedirect: 301: Moved Permanently

それは私のコードにぶつかっているようにも見えません。むしろ、トレースバックがその中のファイルを表示していません。ある時点で、Nginxにすべての非SSLリクエストをHTTPSにリダイレクトさせましたが、Varnishがエラーなしでポート443にリクエストを送信できなかったため、これを無効にする必要がありました。作りません。

ただし、常に301が返されるわけではありませんが、URLを要求して問題なく取得できます。しかし、URLをリクエストしている世界中の誰かが301応答を受け取っています。

これは、アカウントにリンクするためのいくつかのカスタムヘッダーを含むGETリクエストです。

私のコードには、301リダイレクトはありません。

25
Nalum

トレースバックは、リダイレクトを引き起こしたのはルートマッチングであったことを示しています。 通常(たとえば、明示的なリダイレクトルートを追加しない限り)、つまり、クライアントがbranchURL(末尾のスラッシュで終わるURL)ですが、要求されたURLには最後のスラッシュが含まれていませんでした。クライアントは、スラッシュを使用して正規ブランチURLにリダイレクトされます

Werkzeug Rule documentation から:

スラッシュで終わるURLルールはブランチURLで、その他はリーフURLです。 strict_slashesを有効にしている場合(デフォルト)、末尾のスラッシュなしで一致するすべてのブランチURLは、欠落しているスラッシュが追加された同じURLへのリダイレクトをトリガーします。

ルーティングドキュメント から:

FlaskのURLルールは、Werkzeugのルーティングモジュールに基づいています。このモジュールの背後にある考え方は、Apacheや以前のHTTPサーバーによって定められた前例に基づいて、美しくユニークなURLを確保することです。

次の2つのルールを取ります。

@app.route('/projects/')
def projects():
    return 'The project page'

@app.route('/about')
def about():
    return 'The about page'

見た目はかなり似ていますが、URL定義の末尾のスラッシュの使い方が異なります。最初のケースでは、プロジェクトエンドポイントの正規URLの末尾にスラッシュがあります。その意味では、ファイルシステム上のフォルダーに似ています。末尾にスラッシュを付けずにアクセスすると、Flaskは末尾のスラッシュを含む正規URLにリダイレクトされます。

ただし、2番目の場合、URLはUNIXライクなシステムのファイルのパス名のように、末尾にスラッシュを付けずに定義されます。末尾にスラッシュを付けてURLにアクセスすると、404「見つかりません」エラーが発生します。

この動作により、末尾のスラッシュが省略されていても、Apacheや他のサーバーの動作と一致して、相対URLが機能し続けることができます。また、URLは一意のままであるため、検索エンジンが同じページを2回インデックスに登録するのを回避できます。

文書化されているように、しない場合はこの動作が必要です(そしてURLがなし末尾のスラッシュは代わりに404 Not Foundです)、ルートにstrict_slashes=Falseオプションを設定する必要があります。

54
Martijn Pieters