python Django框架實(shí)現(xiàn)自定義表單提交
除了使用Django內(nèi)置表單,有時往往我們需要自定義表單。對于自定義表單Post方式提交往往會帶來由CSRF(跨站請求偽造)產(chǎn)生的錯誤"CSRF verification failed. Request aborted."
本篇文章主要針對"表單提交"和"Ajax提交"兩種方式來解決CSRF帶來的錯誤
一、表單提交
Template:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>計算數(shù)字和</title>
</head>
<body>
<form method="post" action="{%url 'Calculate' %}">
{% csrf_token %}
<label for="A"><input id="A" name="ValueA" type="text"></label>
<label for="B"><input id="B" name="ValueB" type="text"></label>
<input type="submit" value="開始計算">
</form>
</body>
</html>
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)在<form>標(biāo)簽內(nèi)添加{% csrf_token %},這樣在表單提交的過程中,會產(chǎn)生"csrfmiddlewaretoken"標(biāo)識去防止CSRF
(2)在Get請求頁面時,需要添加context_instance=RequestContext(request) ,它和{% csrf_token %}配合使用,缺少一個都會出現(xiàn)上述錯誤,RequestContext 需要在 django.shortcuts 導(dǎo)入
(3)只有當(dāng)表單以Post方式提交時,才需要驗(yàn)證CSRF,Get方式是不需要的
二、Ajax提交
同比與表單提交,Ajax提交需要進(jìn)行額外的操作,Ajax提交時需要自己提供"csrfmiddlewaretoken"標(biāo)識參數(shù)。我們除了需要引入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:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Ajax 提交</title>
<script type="text/javascript" src="/static/jquery.js"></script>
<script type="text/javascript">
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>
<script type="text/javascript">
$(function(){
$.ajaxSetup({
data:{csrfmiddlewaretoken: '{{ csrf_token }}'}
});
$("#Comment").click(function(){
$.post('{% url 'AjaxRequest' %}',{"a":$("#A").val(),"b":$("#B").val()},function(data){
$("#result").html(data);
});
});
});
</script>
</head>
<body>
<label for="A"><input id="A" name="ValueA" type="text"></label>
<label for="B"><input id="B" name="ValueB" type="text"></label>
<input type="button" id="Comment" value="開始計算">
<h1>計算的結(jié)果為:<span id="result"></span></h1>
</body>
</html>
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"標(biāo)識,接下來你就可以使用$.post()了
$.ajaxSetup({
data:{csrfmiddlewaretoken: '{{ csrf_token }}'}
});
(2)context_instance=RequestContext(request) 并不是必須的
(3)Get請求不需要以上操作,直接使用$.get()即可
注:本文使用的Django1.8.3版本進(jìn)行測試。
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助。
相關(guān)文章
通過實(shí)例了解Python str()和repr()的區(qū)別
這篇文章主要介紹了通過實(shí)例了解Python str()和repr()的區(qū)別,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2020-01-01
python實(shí)現(xiàn)二維數(shù)組的對角線遍歷
這篇文章主要為大家詳細(xì)介紹了python實(shí)現(xiàn)二維數(shù)組的對角線遍歷,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2019-03-03
python學(xué)生管理系統(tǒng)代碼實(shí)現(xiàn)
這篇文章主要為大家詳細(xì)介紹了python學(xué)生管理系統(tǒng)代碼實(shí)現(xiàn),文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2018-03-03
手把手教你配置JupyterLab 環(huán)境的實(shí)現(xiàn)
這篇文章主要介紹了手把手教你配置JupyterLab 環(huán)境,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-02-02

