現有以下模板和視圖:html
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>登陸</title> 6 </head> 7 <body> 8 <form action="/login/" method="post"> 9 <p>用戶名:<input type="text" name="username"></p> 10 <p>密碼:<input type="text" name="password"></p> 11 <p><input type="submit" value="提交"></p> 12 <p style="color: red"> {{ msg }}</p> 13 </form> 14 </body> 15 </html>
1 from django.shortcuts import render,HttpResponse 2 3 4 def login(request): 5 if request.method == 'POST': 6 username = request.POST.get('username') 7 password = request.POST.get('password') 8 print(username, password) 9 return HttpResponse('登錄成功') 10 else: 11 return render(request, 'login.html')
使用上述模板中表單直接進行提交時,會發現會返回403錯誤以下:jquery
這是由於Django中默認配置了一個攔截CSRF請求的中間件,在settings.py中可配置:ajax
1 MIDDLEWARE = [ 2 'django.middleware.security.SecurityMiddleware', 3 'django.contrib.sessions.middleware.SessionMiddleware', 4 'django.middleware.common.CommonMiddleware', 5 'django.middleware.csrf.CsrfViewMiddleware', # 此項即是攔截CSRF請求的中間件 6 'django.contrib.auth.middleware.AuthenticationMiddleware', 7 'django.contrib.messages.middleware.MessageMiddleware', 8 'django.middleware.clickjacking.XFrameOptionsMiddleware', 9 ]
直接註釋該行便可。django
1 MIDDLEWARE = [ 2 'django.middleware.security.SecurityMiddleware', 3 'django.contrib.sessions.middleware.SessionMiddleware', 4 'django.middleware.common.CommonMiddleware', 5 # 'django.middleware.csrf.CsrfViewMiddleware', # 此項即是攔截CSRF請求的中間件 6 'django.contrib.auth.middleware.AuthenticationMiddleware', 7 'django.contrib.messages.middleware.MessageMiddleware', 8 'django.middleware.clickjacking.XFrameOptionsMiddleware', 9 ]
註釋以後就能夠正常提交請求了。服務器
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>登陸</title> 6 </head> 7 <body> 8 <form action="/login/" method="post"> 9 {% csrf_token %} 10 <p>用戶名:<input type="text" name="username"></p> 11 <p>密碼:<input type="text" name="password"></p> 12 <p><input type="submit" value="提交"></p> 13 <p style="color: red"> {{ msg }}</p> 14 </form> 15 </body> 16 </html>
在表單中添加上‘{%csrf_token%}’以後,查看網頁源代碼會發現表單中多了一個隱藏的輸入框,以下:cookie
Django經過這種方式讓表單的請求帶着token一塊兒發送到服務器去驗證。session
修改login.html內容以下:ide
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>登陸</title> 6 <script src="/static/jquery.min.js"></script> 7 </head> 8 <body> 9 <script> 10 function login() { 11 $.ajax({ 12 url: "/login/", 13 type: "POST", 14 data: {"usr": "admin", "pwd": "123"}, 15 {#headers:{ "X-CSRFtoken":$.cookie("csrftoken")},#} 16 success: function (data) { 17 alert(data) 18 } 19 }) 20 } 21 login() 22 </script> 23 </body> 24 </html>
訪問該頁面會發現與表單請求同樣被攔截:函數
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>登陸</title> 6 <script src="/static/jquery.min.js"></script> 7 </head> 8 <body> 9 <script> 10 function login() { 11 $.ajax({ 12 url: "/login/", 13 type: "POST", 14 data: {"usr": "admin", "pwd": "123"}, 15 headers: { 16 "X-CSRFtoken": '{{csrf_token}}' 17 }, 18 success: function (data) { 19 alert(data) 20 } 21 }) 22 } 23 login() 24 </script> 25 </body> 26 </html>
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>登陸</title> 6 <script src="/static/jquery.min.js"></script> 7 </head> 8 <body> 9 {% csrf_token %} 10 <script> 11 function login() { 12 $.ajax({ 13 url: "/login/", 14 type: "POST", 15 data: {"usr": "admin", "pwd": "123", "csrfmiddlewaretoken": '{{csrf_token}}'}, 16 success: function (data) { 17 alert(data) 18 } 19 }) 20 } 21 22 login() 23 </script> 24 </body> 25 </html>
若是頁面中有多個ajax請求的話就能夠經過下面方式在全部的ajax中添加headers信息:post
$.ajaxSetup({ beforeSend: function (xhr, settings) { xhr.setRequestHeader("X-CSRFtoken", '{{csrf_token}}') } });
這樣就會在提交ajax以前執行這個方法,從而在全部的ajax裏都加上這個csrftoken。
若是想要實如今當get方式的時候不須要提交csrftoken,當post的時候須要,實現這種效果的代碼以下:
function csrfSafeMethod(method) { return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method)); } $.ajaxSetup({ beforeSend: function (xhr, settings) { if (!csrfSafeMethod(settings.type) && !this.crossDomain) { xhr.setRequestHeader("X-CSRFToken", '{{ csrf_token }}'); } } });
上述示例因csrf_token都是經過模板語言取出,因此html頁必須由django的render函數渲染過。同理也可經過js取出cookie中csrf_token值,填充到對應位置便可。
from django.views.decorators.csrf import csrf_exempt @csrf_exempt def view_func(request): pass