質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Flask

FlaskはPython用のマイクロフレームワークであり、Werkzeug・Jinja 2・good intentionsをベースにしています。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Q&A

解決済

2回答

1306閲覧

@app.route('/upload')に末尾の/を入れると画像が表示されない。

ikidaore

総合スコア4

Flask

FlaskはPython用のマイクロフレームワークであり、Werkzeug・Jinja 2・good intentionsをベースにしています。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

0グッド

0クリップ

投稿2019/09/30 06:27

前提・実現したいこと

python3.7.4 flask1.1.1 werkzeug0.16.0 を使用してブラウザからアップロードした画像を表示するシステムを作っています。

@app.route('/upload')だと結果ページにアップロードした画像が正しく
表示されますが、@app.route('/upload/')のように末尾にスラッシュを加えると
画像が表示されなくなります。

末尾のスラッシュを記載しても正しく画像が表示されるようにしたいです。

どなたか、ご存知の方、ご回答頂けると幸いです。

発生している問題・エラーメッセージ

【正常時】 127.0.0.1 - - [30/Sep/2019 13:06:07] "GET /static/hoge.jpg HTTP/1.1" 200 - 【エラー時】 127.0.0.1 - - [30/Sep/2019 14:45:24] "GET /upload/static/hoge.jpg HTTP/1.1" 404 -

該当のソースコード

###upload.html

HTML

1<!DOCTYPE html> 2<html> 3 <head> 4 <meta charset="utf-8"/> 5 </head> 6 <body> 7 <h1>画像をアップロード</h1> 8 <form method="POST" action="/upload" enctype="multipart/form-data"> 9 <input placeholder="名前" name="name" type="text"/> 10 <input name="image" type="file"/> 11 <input value="送信" type="submit"/> 12 </form> 13 </body> 14</html>

###result.html

HTML

1<!DOCTYPE html> 2<html> 3 <head> 4 <meta charset="utf-8"/> 5 </head> 6 <body> 7 <h1>アップロードされた画像</h1> 8 <h2>{{name}}</h2> 9 <img src="static/hoge.jpg" style="max-width: 320px"> 10 </body> 11</html>

###error.html

HTML

1<!DOCTYPE html> 2<html> 3 <head> 4 <meta charset="utf-8"/> 5 </head> 6 <body> 7 <h1>不正なリクエストです</h1> 8 </body> 9</html>

###app.py

Python

1from flask import Flask, request, render_template 2from werkzeug.utils import secure_filename 3 4app = Flask(__name__) 5 6@app.route('/upload/', methods=['GET']) 7def render_upload_form(): 8 return render_template('upload.html') 9 10@app.route('/upload/',methods=['POST']) 11def upload_file(): 12 if request.form['name'] and request.files['image']: 13 f = request.files['image'] 14 f.save('static/hoge.jpg') 15 return render_template('result.html',name=request.form['name']) 16 else: 17 return render_template('error.html')

試したこと

@app.route('/upload/')の末尾の/を削除したところ、正しく画像が表示されました。

補足情報(FW/ツールのバージョンなど)

Windows10 VScode を使用して開発しております。

フォルダ構成は以下の通りです。
/
┣ app.py

┣ templates/
┃ ┣ upload.html
┃ ┣ result.html
┃ ┗ error.html

┗ static/
・  ┗ hoge.jpg

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

<form method="POST" action="/upload" enctype="multipart/form-data">

<form method="POST" action="/upload/" enctype="multipart/form-data">

では


すみません。

https://flask.palletsprojects.com/en/1.1.x/api/#url-route-registrations

If a rule ends with a slash and is requested without a slash by the user, the user is automatically redirected to the same page with a trailing slash attached.

が効いていないという主旨の質問でしたら、この回答は不適切ですね。


追記

@app.route('/upload',methods=['POST'])

と書いて/uploadにアクセスすると表示された時のURLは/uploadになります。

@app.route('/upload/',methods=['POST'])

と書いて/uploadにアクセスしても、/uploadというURLに該当する関数は登録されていません。
ですが/を追加すると合致する関数が登録されているなら、HTTPステータスコード308を返し、/upload/にリダイレクトします。
ブラウザは308を受け取って、改めて/upload/にアクセスします。それで処理が行われるので、ブラウザで表示された時そのURLは/upload/になってます。

result.htmlには

<img src="static/hoge.jpg" (略)

と書いてあるので、
前者の場合ブラウザはイメージとして/static/hoge.jpgにアクセスします。
後者の場合ブラウザはイメージとして/upload/static/hoge.jpgにアクセスします。(ページのURLが/upload/ですから)

投稿2019/09/30 06:54

編集2019/09/30 09:42
quickquip

総合スコア11038

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ikidaore

2019/09/30 07:41

quiqui様 ご回答ありがとうございます。 迅速に回答を付けて頂き、とても心強いです。 英語があまり得意ではないので、このページの内容を私が勘違いしていたら申し訳ありません。 @app.routeの末尾にスラッシュが有るか無いかと、ブラウザのURL入力時に末尾にスラッシュがあるかないかで404になるかどうかの関係については、ルーティングのルールを理解しているつもりです。 質問の趣旨としては、 1.末尾スラッシュ有と無しで、result.htmlに表示する画像ファイルのPathが変化するのはなぜなのか? (今回の場合は以下のように) @app.route('/upload/') → /upload/static/hoge.jpg ※404エラー @app.route('/upload')  → /static/hoge.jpg ※表示される 2.末尾のスラッシュがついても正しく表示された時と同じファイルパスで画像を表示するためにどうしたら良いのか。 です。 もしご存知でしたら教えて頂ければ嬉しいです。
ikidaore

2019/09/30 09:56

quiqui様 補足のご回答ありがとうございます。 そういう事だったのですね。 実際に試してみて、動きを把握するようにします。 ご丁寧にありがとうございました。
guest

0

自己解決

解決しました。

result.html の↓の部分を

html

1<img src="static/hoge.jpg" style="max-width: 320px">

↓のように しっかりと相対パスで指定するように書き換えたところ

html

1<img src="../static/hoge.jpg" style="max-width: 320px">

表示されるようになりました。

どうやら@app.routeにバックスラッシュが無い時は、「static/hoge.jpg」の様な指定でもファイルを見つけてくれるようですが、バックスラッシュが有る時は、app.pyの位置から相対パスをしっかり記載しないとダメなようです。

python

1@app.route(/upload) → result.htmlに記載されたパス 2             [static/hoge.jpg][../static/hoge.jpg]どちらでも表示される。 3 4@app.route(/upload/)→ result.htmlに記載されたパス 5             [../static/hoge.jpg]と記載しないと表示されなかった。 6

回答して下さったquiqui様、ありがとうございました。
お騒がせ致しました。

投稿2019/09/30 09:13

ikidaore

総合スコア4

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問