Vue.jsとPython 3のFlaskで連携をとっていた時の問題。
問題
jQueryのajaxで返り値がとれない
$.ajax({
url: "http://127.0.0.1:5000/upload",
type: "POST",
data: JSON.stringify(data),
timeout: 10000,
})
.done(function(res) {
// 成功時の動作
})
.fail(function(XMLHttpRequest, textStatus, errorThrown) {
// 失敗時の動作
})
@app.route('/test', methods=['POST'])
def test():
data = request.data
# 処理
return "これが届かなーい"
POSTしたデータを処理し、何らかの値を返す際にエラーが出た。サーバー側は200を出しているのでサーバーには問題なく届いている。
解決策
Ajax側の設定(Content-Typeなど)かと思ったがそうではないらしい。散々調べて行き着いたのがAccess-Control-Allow-Origin
の問題。何回も見ましたけどね。
引っかかったポイント
from flask_cors import CORS
app = Flask(__name__, template_folder='templates')
cors = CORS(app, resources={r"/api/*": {"origins": "*"}})
これを挟めばいいですよーという情報がたくさんあるが、これではなかった。これのせいで時間を取られた。
Python 2 系の方法
Python 2 系の方法があるとのことで試してみる。上のコードを修正。
api = Flask(__name__)
@api.after_request
def after_request(response):
response.headers.add('Access-Control-Allow-Origin', '*')
response.headers.add('Access-Control-Allow-Headers', 'Content-Type,Authorization')
response.headers.add('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS')
return response
成功。一体なんだったんだ。。。
原因
Access-Control-Allow-Origin
の設定場所については様々な情報があるが、適切な場所に配置してあげないとダメっぽい(当たり前のことだが)。
参考:https://www.hands-lab.com/tech/entry/3716.html
https://stackoverflow.com/questions/22181384/javascript-no-access-control-allow-origin-header-is-present-on-the-requested