ajax头文件报错,AJAX的CSRF保护

如果使用ajax传输数据,需要在AJAX中要使用csrf保护。

一般而言,即在后端已经使用了CSRFProtect(app)的前提下,

如果想使用ajax,避免400的报错,可以前端的表单里引入标签,如下所示

login.html

然后在js中的ajax代码块中将csfr包裹起来:

login.js

$(function () {

$('#submit').click(function (event) {

// 阻止默认的提交表单的行为

event.preventDefault();

var email = $('input[name=email]').val();

var password = $('input[name=password]').val();

var csrftoken = $('input[name=csrf_token]').val()

$.post({

'url': '/login/',

'data': {

'email': email,

'password': password,

'csrf_token':csrftoken

// 把csrf也作为数据传输过去

},

'success': function (data) {

console.log(data);

},

'fail': function (error) {

console.log(error);

}

});

});

});

以上方法是完全可行的,但是太low逼了,虽然后台通过wtform可以正确拿到数据:

form=LoginForm(request.form)

if form.validate():

email=form.email.data

password=form.password.data

print(email,password)

参考官方文档,官方文档给出的建议是如果是ajax,最好是在头文件写csrf-token,即手动的添加X-CSRFToken到Header中。但是CSRF从哪里来,还是需要通过模板给渲染,Flask比较推荐的方式是在前端html文件的meta标签中渲染csrf,如下:

login.html

参考官方文档,如果要发送AJAX请求,则在发送之前要添加CSRF,官网文档里有这样一段很屌的代码如下(使用了jQuery),在头文件里处理了csrftoken:

var csrftoken = $('meta[name=csrf-token]').attr('content')

$.ajaxSetup({

beforeSend: function(xhr, settings) {

if (!/^(GET|HEAD|OPTIONS|TRACE)$/i.test(settings.type) && !this.crossDomain) {

xhr.setRequestHeader("X-CSRFToken", csrftoken)

}

}

})

于是,相应的最初版的login.js改写成如下的形式

login.js

$(function () {

$('#submit').click(function (event) {

// 阻止默认的提交表单的行为

event.preventDefault();

var email = $('input[name=email]').val();

var password = $('input[name=password]').val();

// 得到head中的csrf-token的attr值

var csrftoken = $('meta[name=csrf-token]').attr('content')

$.ajaxSetup({

beforeSend: function(xhr, settings) {

if (!/^(GET|HEAD|OPTIONS|TRACE)$/i.test(settings.type) && !this.crossDomain) {

xhr.setRequestHeader("X-CSRFToken", csrftoken)

}

}

});

$.post({

'url': '/login/',

'data': {

'email': email,

'password': password,

// 注意与最初的版本的不同

},

'success': function (data) {

console.log(data);

},

'fail': function (error) {

console.log(error);

}

});

});

});

这是按照官方文档标准的写法,但是也太麻烦了。。。。。

所以,我们可以自己封装一个myajax.js文件:

myajax.js

var myajax = {

'get':function(args) {

args['method'] = 'get';

this.ajax(args);

},

'post':function(args) {

args['method'] = 'post';

this.ajax(args);

},

'ajax':function(args) {

// 设置csrftoken

this._ajaxSetup();

$.ajax(args);

},

'_ajaxSetup': function() {

$.ajaxSetup({

'beforeSend':function(xhr,settings) {

if (!/^(GET|HEAD|OPTIONS|TRACE)$/i.test(settings.type) && !this.crossDomain) {

var csrftoken = $('meta[name=csrf-token]').attr('content');

xhr.setRequestHeader("X-CSRFToken", csrftoken)

}

}

});

}

};

接着在前端html文件的meta标签中渲染csrf,同时调用myajax.js,如下:

base.html

Title

{% block head %}{% endblock %}

导航条

{% block body %}{% endblock %}

底部栏

附上login.html代码,在其中引入了login.js:

{% extends 'base.html' %}

{% block head %}

{% endblock %}

{% block body %}

邮箱:
密码:

{% endblock %}

最后在login.js中调用封装好的myajax.post替代原声的$.ajax.post:

login.js

/**

* Created by hynev on 2017/11/10.

*/

//jquery

//XMLHTTTPRequest

//整个文档都加载完毕后才会执行这个函数

$(function(){

$('#submit').click(function(event){

//阻止默认的提交表单的行为

event.preventDefault();

varemail=$('input[name=email]').val();

varpassword=$('input[name=password]').val();

myajax.post({

'url':'/login/',

'data':{

'email':email,

'password':password

},

'success':function(data){

console.log(data);

},

'fail':function(error){

console.log(error);

}

});

});

});

这个myajax.js这个文件可以直接用在很多地方。

  • 0
    点赞
  • 0
    评论
  • 0
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

表情包
插入表情
评论将由博主筛选后显示,对所有人可见 | 还能输入1000个字符
©️2021 CSDN 皮肤主题: 数字20 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值