【发布时间】:2017-11-17 13:45:56
【问题描述】:
我正在制作一个用于发送电子邮件的 Flask 应用程序。它工作得很好,直到我决定实现一点 AJAX 以使其更具交互性。
我经常收到 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 = 'jakov.kusic92@gmail.com',
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='jakov.kusic92@gmail.com',
recipients=['jakov.kusic@gmail.com']
)
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 开发工具上获得的:
【问题讨论】: