2022-10-17

flask

python

Posted by

applemango

さて、前回はerrorが出た所で終わりました

今回はそのerrorを解決していきましょう

参考までにここまでのapp.pyのprogramを載せておきます

import os #pathの取得などに使う
import json #何かと使う
from flask import Flask # flaskを使うのに絶対必要
from flask import jsonify # jsonを送るのに使う
from flask import request # queryなどを取得するのに使う
from flask_cors import CORS, cross_origin#crosの設定
from flask_sqlalchemy import SQLAlchemy#databaseを使うために必要

basedir = os.path.abspath(os.path.dirname(__file__)) #実行folderのpathを取得、何かと使う

app = Flask(__name__, instance_relative_config=True) # アプリの作成
app.config.from_mapping( #アプリの設定
    None #今は何も無い
)

@app.route("/get/<id>")
def get_url(id):
    return jsonify({"url":"https://example.com"})

@app.route("/create")
def create_url():
    return jsonify({"url":"https://exmaple.com"})

if __name__ == '__main__':
    app.run(debug=True, host='0.0.0.0', port=5000) # アプリの実行

バグなど入り込む隙もなさそうなプログラムですね

ですがnetwork errorとは何でしょう

なぜgetでは出なかったerrorがpostで出たのでしょう

結論から言いましょうCORSが原因です

やっと最初の方に出た伏線が回収されましたね

#伏線達 (このコード達は関係無いよ? 無視して?
%pip install flask_cors
from flask_cors import CORS, cross_origin

解決は意外と簡単です

以下のように変更するだけです

warning

今回はtutorialの都合上一番簡単な方法を取っています

実際に使用する際には予期せぬ事態の発生や脆弱性が発生する可能性が有ります

良く調べてから使用してください

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

+

16

17

18

19

20

21

22

+

23

24

25

26

27

import os #pathの取得などに使う
import json #何かと使う
from flask import Flask # flaskを使うのに絶対必要
from flask import jsonify # jsonを送るのに使う
from flask import request # queryなどを取得するのに使う
from flask_cors import CORS, cross_origin#crosの設定
from flask_sqlalchemy import SQLAlchemy#databaseを使うために必要

basedir = os.path.abspath(os.path.dirname(__file__)) #実行folderのpathを取得、何かと使う

app = Flask(__name__, instance_relative_config=True) # アプリの作成
app.config.from_mapping( #アプリの設定
    None #今は何も無い
)
cors = CORS(app, responses={r"/*": {"origins": "*"}})

@app.route("/get/<id>")
def get_url(id):
    return jsonify({"url":"https://example.com"})

@app.route("/create")
@cross_origin()
def create_url():
    return jsonify({"url":"https://exmaple.com"})

if __name__ == '__main__':
    app.run(debug=True, host='0.0.0.0', port=5000) # アプリの実行

パット見何が変わったか分かりませんね

ですが二行新しく追加されています

cors = CORS(app, responses={r"/*": {"origins": "*"}})
@cross_origin()

一行目はCORSを設定しています

設定と解説がめんどくさいので全てを許可しています

warning

先ほども言った通りこの設定は避けた方が良いです

ですが外部に公開しなければ問題ありません

2行目はErrorが出た関数(/createにpostした時にErrorが出た)に付けています

これもデコレーターです

これで実行してみましょう

おーい、いい加減にしろよ

そう思った事だろう

AxiosError: Request failed with status code 405とerrorが出ただろうF12を押し開発者モードを立ち上げNetworkから通信を確認しながらもう一度requestを送って見よう

すると一つ赤く表示された通信があるだろう

確認するとhttp://127.0.0.1:5000/createに送られた通信で405 METHOD NOT ALLOWEDと帰ってきている

何故postしただけでこんなにErrorが出るのだろうかと思いつつ解決しよう

理由はデコレーターが原因だ今関数`create_url`は以下のようなデコレーターになっている

(本来は二つありますがCORSの方は関係ないので無視してください

@app.route("/create")

これだとgetしか出来ないのだ

実はこれ以下のと意味は同じなのだ

@app.route("/create", methods=["GET"])

そうgetしかdefaultでは受け付けないのだ

だから以下のように修正しないといけない

@app.route("/create", methods=["POST"])

これでpostできるようになった

さっき動かなかったテストも今はもう動くだろう

warning

サーバーが実行されている必要が有ります

createはこのような

{
  "url": "https://example.com"
}

getも同じように出てくる

今は何を入れても同じものが出てくるが次回にはちゃんと違う物が出てくるようになるはずです...

{
  "url": "https://example.com"
}

これでfrontendは完成した

backendも後はdbを作って関数get_urlcreate_urlを変更するだけだ

次回、僕の嫌いなDB

乞うご期待

このドキュメントどう?

emoji
emoji
emoji
emoji