
flaskでreactからPOSTメソッドで値を受け取りたい
flask, sqlAlchemy(api)とreact(画面側)でECサイトを練習で作っています。
画面側でフォームに入力された値をapiで取得しDBに保存する機能を作る際に、
エラーが表示され困っております。
現在、デバッグで確認したところ、
DEBUG in app: ImmutableMultiDict([('{"name":"白いズボン","price":"4000","imgLink":"p5.jpg","detail":"綺麗なシルエットです。"}', '')])
取得できていそうだが、上手くデータが認識されていないようでした。
実現したいこと
- apiで画面のフォームから受け取った値を取得したい。
発生している問題・エラーメッセージ
werkzeug.exceptions.BadRequestKeyError: 400 Bad Request: The browser (or proxy) sent a request that this server could not understand. KeyError: 'name'
Access to XMLHttpRequest at 'http://0.0.0.0:5000/create' from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
POST http://0.0.0.0:5000/create net::ERR_FAILED 500
該当のソースコード
flask(app.py)
1# coding: UTF-8 2from nis import cat 3import os 4from itertools import product 5from pickle import TRUE 6from re import template 7from unicodedata import category, name 8from click import format_filename 9from flask import * 10from flask import request 11from flask_sqlalchemy import SQLAlchemy 12from werkzeug.utils import secure_filename 13import psycopg2 14# from flask_marshmallow import Marshmallow 15from marshmallow_sqlalchemy import SQLAlchemyAutoSchema 16from flask_cors import CORS, cross_origin 17 18# データベースのファイルパスを作成。 19basedir = os.path.abspath(os.path.dirname(__file__)) 20 21app = Flask(__name__, static_url_path='', static_folder='./practice_react_app/build', template_folder='./practice_react_app/build') 22CORS(app, origins=["localhost:3000"]) 23 24app.config['DEBUG'] = True 25app.config['SQLALCHEMY_DATABASE_URI'] = "postgresql+psycopg2://xxxxx.xxxxxx@localhost:5432/xxxx_db" 26app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False 27 28 29db = SQLAlchemy(app) 30db.init_app(app) 31 32class Product(db.Model): 33 id = db.Column(db.Integer, primary_key=True, 34 nullable=False, autoincrement=True) 35 name = db.Column(db.String(30)) 36 price = db.Column(db.Integer) 37 detail = db.Column(db.String(200)) 38 imgLink = db.Column(db.String(30)) 39 40@app.route('/create', methods=['POST']) 41@cross_origin(supports_credentials=True) 42def insert(): 43 app.logger.debug(request.form) // debug調査用 44 if request.method == 'POST': 45 46 form_name = request.form['name'] 47 form_price = request.form['price'] 48 form_detail = request.form['detail'] 49 form_imgLink = request.form['imgLink'] 50 # form_category = request.form.get('category') 51 52 product = Product( 53 name=form_name, 54 price=form_price, 55 detail=form_detail, 56 imgLink=form_imgLink 57 ) 58 db.session.add(product) 59 db.session.commit() 60 return redirect('http://localhost:3000', code=200) 61 62if __name__ == '__main__': 63 app.run(host="0.0.0.0", port=int("5000"), debug=True)
react(addProduct.jsx)
1import { useForm } from "react-hook-form"; 2import axios from 'axios'; 3 4export const AddProduct = () => { 5 const { register, formState: { errors }, handleSubmit } = useForm({ 6 defaultValues: { 7 name: '', 8 price: 0, 9 imgLink: '', 10 detail: '' 11 } 12 }); 13 const postData = (data) => { 14 const name = data.name; 15 const price = Number(data.price); 16 const imgLink = data.imgLink; 17 const detail = data.detail; 18 19 const postURL = "http://0.0.0.0:5000/create" 20 axios.post(postURL, data, 21 {headers: {'Content-Type': 'application/x-www-form-urlencoded'}}) 22 .then(function (response) { 23 console.log(response); 24 }) 25 .catch(function (error) { 26 console.log(error); 27 }); 28 }; 29 30 return ( 31 <div> 32 <form onSubmit={handleSubmit(postData)}> 33 <label >商品名:</label> 34 <br /> 35 <input 36 {...register("name", { required: true })} 37 aria-invalid={errors.firstName ? "true" : "false"} 38 /> 39 {errors.name?.type === 'required' && <p role="alert">商品名を入力してください。</p>} 40 <br /> 41 42 <label >値段:</label> 43 <br /> 44 <input type="text" inputmode="numeric" 45 {...register("price", { required: true })} 46 aria-invalid={errors.price ? "true" : "false"} 47 />円 48 {errors.price?.type === 'required' && <p role="alert">値段を入力してください。</p>} 49 <br /> 50 51 52 <label >画像リンク:</label> 53 <br /> 54 <input 55 {...register("imgLink", { required: true })} 56 aria-invalid={errors.imgLink ? "true" : "false"} 57 /> 58 {errors.imgLink?.type === 'required' && <p role="alert">画像のリンクを入力してください。</p>} 59 <br /> 60 61 62 <label >詳細:</label> 63 <br /> 64 <input 65 {...register("detail", { required: true })} 66 aria-invalid={errors.detail ? "true" : "false"} 67 /> 68 {errors.detail?.type === 'required' && <p role="alert">詳細を入力してください。</p>} 69 <br /> 70 71 <input type="submit" /> 72 </form> 73 </div> 74 );
試したこと
Access-Control-Allow-Origin:*
を設定
補足情報(FW/ツールのバージョンなど)
python 3.9.0


回答2件
あなたの回答
tips
プレビュー