pythondjango框架实现自定义表单提交

除了使用django内置表单,有时往往我们需要自定义表单。对于自定义表单post方式提交往往会带来由csrf(跨站请求伪造)产生的错误”csrf verification failed. request aborted.”

本篇文章主要针对”表单提交”和”ajax提交”两种方式来解决csrf带来的错误

一、表单提交
template:

计算数字和

{% csrf_token %}

views.py:

def calculate(request):
if request.post:
a=request.post[“valuea”]
b=request.post[“valueb”]
c=str(int(a)+int(b))
return render_to_response(‘result.html’,{‘result’:c})
else:
return render_to_response(‘calculation.html’,context_instance=requestcontext(request))

需要注意:

(1)在标签内添加{% csrf_token %},这样在表单提交的过程中,会产生”csrfmiddlewaretoken”标识去防止csrf

(2)在get请求页面时,需要添加context_instance=requestcontext(request) ,它和{% csrf_token %}配合使用,缺少一个都会出现上述错误,requestcontext 需要在 django.shortcuts 导入

(3)只有当表单以post方式提交时,才需要验证csrf,get方式是不需要的

二、ajax提交
同比与表单提交,ajax提交需要进行额外的操作,ajax提交时需要自己提供”csrfmiddlewaretoken”标识参数。我们除了需要引入jquery外还需要引入一段js代码

jquery(document).ajaxsend(function(event, xhr, settings) {
function getcookie(name) {
var cookievalue = null;
if (document.cookie && document.cookie != ”) {
var cookies = document.cookie.split(‘;’);
for (var i = 0; i < cookies.length; i++) { var cookie = jquery.trim(cookies[i]); // does this cookie string begin with the name we want? if (cookie.substring(0, name.length + 1) == (name + '=')) { cookievalue = decodeuricomponent(cookie.substring(name.length + 1)); break; } } } return cookievalue; } function sameorigin(url) { // url could be relative or scheme relative or absolute var host = document.location.host; // host + port var protocol = document.location.protocol; var sr_origin = '//' + host; var origin = protocol + sr_origin; // allow absolute or scheme relative urls to same origin return (url == origin || url.slice(0, origin.length + 1) == origin + '/') || (url == sr_origin || url.slice(0, sr_origin.length + 1) == sr_origin + '/') || // or any other url that isn't scheme relative or absolute i.e relative. !(/^(\/\/|http:|https:).*/.test(url)); } function safemethod(method) { return (/^(get|head|options|trace)$/.test(method)); } if (!safemethod(settings.type) && sameorigin(settings.url)) { xhr.setrequestheader("x-csrftoken", getcookie('csrftoken')); } });

template:

ajax 提交
《script》

jquery(document).ajaxsend(function(event, xhr, settings) {
function getcookie(name) {
var cookievalue = null;
if (document.cookie && document.cookie != ”) {
var cookies = document.cookie.split(‘;’);
for (var i = 0; i < cookies.length; i++) { var cookie = jquery.trim(cookies[i]); // does this cookie string begin with the name we want? if (cookie.substring(0, name.length + 1) == (name + '=')) { cookievalue = decodeuricomponent(cookie.substring(name.length + 1)); break; } } } return cookievalue; } function sameorigin(url) { // url could be relative or scheme relative or absolute var host = document.location.host; // host + port var protocol = document.location.protocol; var sr_origin = '//' + host; var origin = protocol + sr_origin; // allow absolute or scheme relative urls to same origin return (url == origin || url.slice(0, origin.length + 1) == origin + '/') || (url == sr_origin || url.slice(0, sr_origin.length + 1) == sr_origin + '/') || // or any other url that isn't scheme relative or absolute i.e relative. !(/^(\/\/|http:|https:).*/.test(url)); } function safemethod(method) { return (/^(get|head|options|trace)$/.test(method)); } if (!safemethod(settings.type) && sameorigin(settings.url)) { xhr.setrequestheader("x-csrftoken", getcookie('csrftoken')); } }); 《script》 $(function(){ $.ajaxsetup({ data:{csrfmiddlewaretoken: '{{ csrf_token }}'} }); $("#comment").click(function(){ $.post('{% url 'ajaxrequest' %}',{"a":$("#a").val(),"b":$("#b").val()},function(data){ $("#result").html(data); }); }); }); 《script》 计算的结果为:

view.py:

def ajaxrequest(request):
if request.post:
a =request.post[“a”]
b=request.post[“b”]
c=int(a)+int(b)
return jsonresponse(c,safe=false)
else:
return render_to_response(‘ajaxdemo.html’,context_instance=requestcontext(request))

需要注意:

(1)在使用引入的js代码后,需要添加如下代码,这样js就可以自动帮我们生成”csrfmiddlewaretoken”标识,接下来你就可以使用$.post()了

$.ajaxsetup({
data:{csrfmiddlewaretoken: ‘{{ csrf_token }}’}
});

(2)context_instance=requestcontext(request) 并不是必须的

(3)get请求不需要以上操作,直接使用$.get()即可
注:本文使用的django1.8.3版本进行测试。

以上就是本文的全部内容,希望对大家的学习有所帮助。

Posted in 未分类