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