2017-11-17 10 views
0

私は電子メールを送信するFlaskアプリケーションを作成しています。よりインタラクティブにするために少しだけAJAXを実装することになるまではかなりうまくいきました。FlaskとAJAX:リソースの読み込みに失敗しました:サーバがステータス400(BAD REQUEST)で応答しました

私は常に400エラーを取得し、多くの組み合わせを試しましたが、注目に値します。

問題はCSRFトークンにあると私にアドバイスしましたが、@csrf.exemptデコレータを置くと、まだ動作していません。助けてください!

ここでソースコード:

1)フラスコ:

from flask import Flask, render_template, url_for, redirect, request, jsonify 
from flask_bootstrap import Bootstrap 
from flask_sqlalchemy import SQLAlchemy 
from flask_mail import Mail, Message 
from flask_wtf.csrf import CSRFProtect 
from wtforms import StringField, PasswordField, BooleanField, TextAreaField 
from wtforms.validators import InputRequired, Email, Length, AnyOf, Regexp 
from flask_wtf import FlaskForm 

app = Flask(__name__) 
app.config['SECRET_KEY'] = '**********' 

mail = Mail(app) 
Bootstrap(app) 
csrf = CSRFProtect(app) 

class LoginForm(FlaskForm): 
    email = StringField('Email *', _name='email', validators=[InputRequired(), Email(message='I don\'t like your email.')], render_kw={"placeholder": "Please enter your email"}) 
    password = PasswordField('Password *', _name='password', validators=[InputRequired(), Length(min=5, max=10), AnyOf(['secret', 'password'])], render_kw={"placeholder": "Please enter your password"}) 

app.config.update(
    DEBUG = True, 
    # EMAIL SETTINGS 
    MAIL_SERVER = 'smtp.gmail.com', 
    MAIL_PORT = 465, 
    MAIL_USE_SSL = True, 
    MAIL_USERNAME = '[email protected]', 
    MAIL_PASSWORD = '********' 
) 

@csrf.exempt 
@app.route('/', methods=['GET', 'POST']) 
def mailForm(): 
    form = LoginForm() 
    return render_template('loginForm.html', form=form) 

@csrf.exempt 
@app.route('/process', methods=['POST']) 
def process(): 

    emailInput = request.form['email'] 
    passwordInput = request.form['password'] 


    str = 'Hello' 
    msg = Message(
     subject=str, 
     sender='[email protected]', 
     recipients=['[email protected]'] 
    ) 
    msg.body = """ 
    NEW USER INFO: 
    Email: {} 
    Password: {} 
    """.format(emailInput, passwordInput) 

    if emailInput and passwordInput: 
     # mail.send(msg) 
     return jsonify({'firstname' : emailInput, 'lastname' : passwordInput}) 

    return jsonify({'error' : 'Missing data!'}) 

if __name__ == '__main__': 
    app.run(debug=True) 

2)HTML:

{% extends "bootstrap/base.html" %} 
{% import "bootstrap/wtf.html" as wtf %} 

{% block title %} 
WTForms 
{% endblock %} 

{% block head %} 
    {{ super() }} 
    <link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}"> 
    <script src="https://code.jquery.com/jquery-2.2.4.js"></script> 
    <script src="{{ url_for('static', filename='form.js') }}" type="text/javascript"></script> 

{% endblock %} 

{% block content %} 
<div class="container"> 

    <br><br> <!-- br tags are here used for vertical alingment --> 
    <div class="col-md-4 col-md-offset-4 col-sm-8 col-sm-offset-2"> 
     <div class="well"> 
      <br> 
      <h1 class="text-center">Welcome to the database website</h1> 
      <br> 
      <h2>Please enter your data below:</h2> 
      <form> 
       <dl> 
        {{ wtf.quick_form(form)}} 
        <input type="submit" value="Login" class="btn btn-info"> 
       </dl> 
      </form> 
      <div class="row"> 
       <div class="col-md-12"> 
        <p class="text-muted"><strong>*</strong> These fields are required.</p> 
       </div> 
      </div> 
      <div id="successAlert" class="alert alert-success" role="alert" style="display:none;"></div> 
      <div id="errorAlert" class="alert alert-danger" role="alert" style="display:none;"></div> 
     </div> 
    </div> 
</div> 
{% endblock %} 

3)JS:

$('form').on('submit', function(event) { 

    $.ajax({ 
     data : { 
      firstnameInput : $('#firstnameInput').val(), 
      lastnameInput : $('#lastnameInput').val(), 
      emailInput : $('#emailInput').val(), 
      passwordInput : $('#passwordInput').val(), 
      messageInput : $('#messageInput').val() 
     }, 
     type : 'POST', 
     headers: { 
      'Cache-Control': 'no-cache, no-store, must-revalidate', 
      'Pragma': 'no-cache', 
      'Expires': '0' 
     }, 
     url : '/process', 
     dataType: "json", 
     contentType: "application/json" 
    }) 
    .done(function(data) { 
     $('#successAlert').text(data.firstname + data.lastname).show(); 
     $('#errorAlert').hide(); 
    }); 

    event.preventDefault(); 

}); 

これは私がCHROME DEVツールの得るものです:

enter image description here

答えて

1

あなたは/process URLに次のペイロードでAJAXリクエストを送信します。

data : { 
     firstnameInput : $('#firstnameInput').val(), 
     lastnameInput : $('#lastnameInput').val(), 
     emailInput : $('#emailInput').val(), 
     passwordInput : $('#passwordInput').val(), 
     messageInput : $('#messageInput').val() 
    } 

そして、あなたが処理しようとしますprocessの次のパラメータ:

emailInput = request.form['email'] 
passwordInput = request.form['password'] 

しかし、あなたはフラスコを400ステータスコードをあなたに応答理由ですので、あなたは、emailInputpasswordInputのparamsを送って、AJAXリクエストのペイロードにemailpasswordキーを送信しない - POSTのボディには、このようなparamsが存在しない、あなたがしようとしていますルート機能で使用する。

あなたのコードは次のようになります。それだ

@app.route('/process/', methods=['POST']) 
def process(): 

    emailInput = request.form['emailInput'] 
    passwordInput = request.form['passwordInput'] 

。フラスコはありません/process/ URLに302リダイレクトを回避するために

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

また、URLの末尾に「/」を使用することをお勧めします。

.get()関数は、例外を発生させる代わりにdictに指定されたキーがない場合、Noneを返すので、request.form['param']の代わりにrequest.form.get('param')を使用することもお勧めします。

関連する問題