ある日ふと、リダイレクトについてどういう動作になっているのか気になり、調べてみることに。
リダイレクトレスポンスはステータスコードが 3 で始まり、 Location ヘッダーがリダイレクト先の URL を保持しています。
とのこと。
- ステータスコードが 3XX 系
- Location ヘッダーがリダイレクト先の URL を保持
ということは分かったけど、両方が必要なのか、どちらかだけで良いかのはっきりかわからなかったので、個人的にハマっている Flask で調べてみることに。
環境
- Windows 10
- Python 3.8.5
- Flask 1.1.2
WSL2 上の Ubuntu で curl が localhost に対してできないことが判明!!
仕方なくPowershell の Invoke-WebRequest 使っています。
通常動作の redirect() をチェック
まずは、通常動作の Flask.redirect() がどういう動作をしているか確認。
# app.py
from flask import Flask, redirect
app = Flask(__name__)
@app.route('/')
def index():
return 'トップページだよ'
@app.route('/redirect')
def my_redirect():
return redirect('/redirected')
@app.route('/redirected')
def redirected():
return 'This is a redirected page'
まずは、flask run
で起動し問題なく動作しているかを確認する。
ブラウザから
localhost:5000
にアクセスして、Flask が問題なく動作していれば、「トップページだよ」が表示される。
エラーが出るとしたら、Flask がインストールされていないか、デフォルトポート(=5000) が開いていない場合ぐらいと思う。
そのまま、curl
や Invoke-WebRequest
でリダイレクトしないようにして、レスポンスヘッダーを確認
Invoke-WebRequest -Uri http://localhost:5000/redirect -MaximumRedirection 0
を実行すると、下記のようになる
RawContent : HTTP/1.0 302 FOUND
Content-Length: 229
Content-Type: text/html; charset=utf-8
Location: http://localhost:5000/redirected
Server: Werkzeug/1.0.1 Python/3.8.5
確かに
- ステータスコードが 302 (= 3XX 系) で
- Location ヘッダーに、リダイレクト先が設定されている
ステータスコードを 200 にしてみる
では、ステータスコードが 3XX 系でない場合どうなるかを確認する。
コードを下記のように変え、ステータスコードを 200 で返してみる
@app.route('/redirect')
def my_redirect():
return redirect('/redirected'), 200
再度、Invoke-WebRequest でアクセスすると
RawContent : HTTP/1.0 200 OK
Content-Length: 229
Content-Type: text/html; charset=utf-8
Location: http://localhost:5000/redirected
Server: Werkzeug/1.0.1 Python/3.8.5
とステータスコードは設定通り 200 となっている。
ブラウザからアクセスするとリダイレクトしないことが確認できる。
Location ヘッダーを削除してみる
ヘッダーを操作するには、make_response()
を使う。
では早速、下記のようにして、別のルーティングで動作を確認。
@app.route('/location-header')
def location_header():
resp = make_response("response from custom header")
# resp.headers['Location'] = '/redirected'
return resp, 302
Invoke-WebRequest で新しく作成した URL にアクセスすると、設定どおりステータスコードが 302 で、Location ヘッダーがないことが確認できる。
RawContent : HTTP/1.0 302 FOUND
Content-Length: 27
Content-Type: text/html; charset=utf-8
Server: Werkzeug/1.0.1 Python/3.8.5
ブラウザからアクセスすると、リダイレクトしないことが確認できる。
コメントをはずし、Location ヘッダーを有効にすると、リダイレクトすることが確認できる。
結論
リダイレクトするには、
- ステータスコードが 3XX 系
- Location ヘッダーがリダイレクト先の URL を保持
の 両方 が必要なことが分かった。