Flaskのデフォルトルートが動作しない問題を修正した

投稿者: | 2019-11-08

Flaskのデフォルトルートが動作しない問題を修正した。

起きた問題

次のようなappのセットアップを行うと、

app = Flask(__name__,
            static_url_path='',
            static_folder="staticdir",
            template_folder="templatedir")

@app.route('/', defaults={'path': ''})
@app.route('/<path:path>')
def index(path):
    print('デバッグ用 path:', path)
    return render_template("index.html")

404のエラーが起こる。/goでも/go/aheadでも404エラーとなる。 default routeとしては、関数index()が呼ばれるべき。

$ curl -I localhost:5000/go
HTTP/1.0 404 NOT FOUND
Content-Type: text/html
Content-Length: 232
Server: Werkzeug/0.16.0 Python/3.8.0
Date: Fri, 08 Nov 2019 02:04:53 GMT

もちろんデバッグ用の出力は出ない。つまり、index()が呼び出されていないということ。

対処法

色々調べると、同じような症状の人はいるようだが、解決までは至っていないようだった。 Flaskのドキュメントを調べたり、debuggerをいじったりして見たが、解決法が不明だった。

しかし、debuggerでurl_mapを見ていると、staticのものとルーティングが似ていることに気づいた。

そこで、

# これはまだ途中
app = Flask(__name__,
            static_url_path='/static',  # 変更
            static_folder="staticdir",
            template_folder="templatedir")

static_url_pathを変更したら、デフォルトルートが動作した。

$ curl -I localhost:5000/go
HTTP/1.0 200 OK
Content-Type: text/html; charset=utf-8
Content-Length: 1103
Server: Werkzeug/0.16.0 Python/3.8.0
Date: Fri, 08 Nov 2019 04:05:06 GMT

$ curl -I localhost:5000/go/ahead
HTTP/1.0 200 OK
Content-Type: text/html; charset=utf-8
Content-Length: 1103
Server: Werkzeug/0.16.0 Python/3.8.0
Date: Fri, 08 Nov 2019 04:05:08 GMT

バックエンド側としてはこれでOK。

なお、このままだと、静的ファイルがおかしくなる(404を返す)ので、それらを修正する必要がある。

フロントエンド側のビルドの設定変更

staticのパスを変更したので、フロントエンド側のビルドの設定も変更する必要がある。 vue.js(cli)を使っているので、assetsDirを使えば良いようだ。 参考: Configuration Reference | Vue CLI

また、この参考ページの上の方にどこに設定を書けば良いか記述がある。

vue.config.js is an optional config file that will be automatically loaded by @vue/cli-service if it's present in your project root (next to package.json). You can also use the vue field in package.json, but do note in that case you will be limited to JSON-compatible values only.

package.jsonに追記する方法をとることにした。

{
  ...
  "vue": {
    "assetsDir": "static"
  },
  ...
}

まだ、jsファイルなどのリソースに対して、404エラーが起こるので、最後の変更を行う。

Flaskのstatic_folderの変更

Flaskのセットアップも少し変更する必要があった。

# 完成版
app = Flask(__name__,
            static_url_path='/static',
            static_folder="staticdir/static",  # static_url_pathと末尾を揃える
            template_folder="templatedir")

上のように、static_url_pathstatic_folderの末尾を揃えておく必要があるようだ。

$ curl -I localhost:5000/static/js/app.js
HTTP/1.0 200 OK
Content-Length: 43466
Content-Type: application/javascript; charset=utf-8
Last-Modified: Fri, 08 Nov 2019 02:37:17 GMT
Cache-Control: public, max-age=43200
Expires: Fri, 08 Nov 2019 16:28:43 GMT
***
Date: Fri, 08 Nov 2019 04:28:43 GMT
Accept-Ranges: bytes
Server: Werkzeug/0.16.0 Python/3.8.0

OK。