🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
HTTP

HTTP(Hypertext Transfer Protocol)とはweb上でHTML等のコンテンツを交換するために使われるアプリケーション層の通信プロトコルです。

リストボックス

ユーザーがリストから1つ以上のアイテムを選択できるようにするGUI要素です。

ルーティング

ルーティングとは、TCP/IPネットワークにおいて、目的のホストまでパケットを送る為のパス選定のプロセスを言います。

サーバ

サーバは、 クライアントサーバモデルにおいてクライアントからの要求に対し 何らかのサービスを提供するプログラムを指す言葉です。 また、サーバーソフトウェアを稼動させているコンピュータ機器そのもののことも、 サーバーと呼ぶ場合もあります。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

2回答

1159閲覧

リストで分岐させたルーティングでアクセスができないページがある

aomatsu_

総合スコア18

HTTP

HTTP(Hypertext Transfer Protocol)とはweb上でHTML等のコンテンツを交換するために使われるアプリケーション層の通信プロトコルです。

リストボックス

ユーザーがリストから1つ以上のアイテムを選択できるようにするGUI要素です。

ルーティング

ルーティングとは、TCP/IPネットワークにおいて、目的のホストまでパケットを送る為のパス選定のプロセスを言います。

サーバ

サーバは、 クライアントサーバモデルにおいてクライアントからの要求に対し 何らかのサービスを提供するプログラムを指す言葉です。 また、サーバーソフトウェアを稼動させているコンピュータ機器そのもののことも、 サーバーと呼ぶ場合もあります。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2020/12/27 10:30

編集2020/12/27 10:31

「pythonフレームワーク Flaskで学ぶWebアプリケーションのしくみと作り方」を学習中です。
p.34の「1-2-6 ルート追加のしくみを考える」で、リストを使ったルーティングを試したところ一部のページでアクセスエラーが発生してしまいました。

実現したいこと

http://localhost:8000/
http://localhost:8000/index
http://localhost:8000/next
にアクセスした際にそのhtmlページを呼び出し、表示させたい。
それ以外のページにアクセスした際にはエラーを出してほしい。

発生する症状

pathを「/」にしたときはindex.htmlが表示されるが、「/index」「/next」のときに404エラーで「nothing matches the given URI.」と表示される。

この参考書の一つ前のステップでは、if文でpathごとにself.index()やself.next()など設定しており、ここまではうまくいっていました。

該当のコード

python

1from urllib.parse import urlparse 2from http.server import BaseHTTPRequestHandler, HTTPServer 3 4# load html file. 5with open ('index.html', mode='r') as f: 6 index = f.read() 7with open ('next.html', mode='r') as f: 8 next = f.read() 9 10routes = [] 11 12def route(path, method): 13 routes.append((path, method)) 14 15# add route setting. 16route('/', 'index') 17route('/index', 'index') 18route('/next', 'next') 19 20class HelloServerHandler(BaseHTTPRequestHandler): 21 22 def do_GET(self): 23 global routes 24 _url = urlparse(self.path) 25 for r in routes: 26 if (r[0] == _url.path): 27 eval('self.' + r[1] + '()') 28 break; 29 else: 30 self.error() 31 return 32 33 # index action. 34 def index(self): 35 self.send_response(200) 36 self.end_headers() 37 html = index.format( 38 title='Hello', 39 message='ようこそ、HTTPServerの世界へ!!' 40 ) 41 self.wfile.write(html.encode('utf-8')) 42 return 43 44 # next action. 45 def next(self): 46 self.send_response(200) 47 self.end_headers() 48 html = next.format( 49 message='this is next page.', 50 data='{\n data:"this is data."\n}' 51 ) 52 self.wfile.write(html.encode('utf-8')) 53 return 54 55 # erro action. 56 def error(self): 57 self.send_error(404, "CANNOT ACCESS!!") 58 return 59 60HTTPServer(('',8000),HelloServerHandler).serve_forever()

考えられる原因

リストに3つのタプルがきちんと入っていない

調べたこと・試したこと

Pythonのappend()でリストに要素を追加する | HEADBOOST
appendはリストにしか使えないことはわかったのですが、今回の場合はタプルとして入れている訳では無さそうだったのでわかりませんでした。

関連するソースコード

▼index.html

html

1<!doctype html> 2<html lang="ja"> 3 4<head> 5 <title>{title}</title> 6 <meta charset="utf-8"/> 7 <style> 8 body {{margin:10px;}} 9 h1 {{color:lightgray;font-size:36pt;}} 10 p {{font-size:16pt;}} 11 </style> 12</head> 13 14<body> 15 <h1>{title}</h1> 16 <p>{message}</p> 17</body> 18</html>

▼next.html

html

1<!doctype html> 2<html lang="ja"> 3 4<head> 5 <title>Next</title> 6 <meta charset="utf-8"/> 7 <style> 8 body {{margin:10px;}} 9 h1 {{text-align: right;}} 10 p {{font-size:14pt;}} 11 pre {{background-color:aliceblue;}} 12 </style> 13</head> 14 15<body> 16 <h1>Next Page</h1> 17 <p>{message}</p> 18 <pre>{data}</pre> 19</body> 20</html>

利用環境

python 3.8.3


独学・初心者のためわかりにくいところもあるかと思います。
足りない情報があれば追記しますので、何卒よろしくお願いします。

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

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

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

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

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

guest

回答2

0

自己解決

他のサイトなどでも調べる限りあまり情報が無かったので、リストを使ったルーティングそのものがほぼ不可能と考えることにします。
この件を保留にして教科書を進めてみたところ、Flaskを使う限りルーティングで手間取るところはあまり無さそうだったのでいったん終了とさせていただきます。ご回答ありがとうございました。

投稿2021/01/04 06:19

aomatsu_

総合スコア18

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

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

0

eval()exec() はちょー危険関数なのでやめましょう。面白いですが。で、一応動くようにするにはどうすればよいかというと、

Python

1hello = HelloServerHandler() 2HTTPServer(('',8000), hello).serve_forever()

とすれば動きます。なんでかはクラスとインスタンスの違いについて調べましょう。

投稿2020/12/27 10:57

A_kirisaki

総合スコア2853

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

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

aomatsu_

2020/12/28 02:41 編集

回答ありがとうございます。 evalは危険なんですね。仰る通り別に実行させるためのプログラムを書くようにします。 この場合、 eval('self.' + r[1] + '()') としていたところはどのように記述したら良いでしょうか?
A_kirisaki

2020/12/28 20:38

単純な話です。if 文を使ってそれぞれ index 関数などを呼べばよいだけなのです。
aomatsu_

2021/01/04 06:19

>この参考書の一つ前のステップでは、if文でpathごとにself.index()やself.next()など設定しており、ここまではうまくいっていました。 と本文にも掲載しておりますように、if文を使ったやり方は一つ前のステップで成功しておりました。 今回は「リストを使った(より簡単な)ルーティング」をお尋ねしたかったのですが、他のサイトなどでも調べる限りあまり情報が無かったので、リストを使ったルーティングそのものがほぼ不可能と考えることにします。 この件を保留にして教科書を進めてみたところ、Flaskを使う限りルーティングで手間取るところはあまり無さそうだったのでいったん終了とさせていただきます。ご回答ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問