Django 中CSRF中間件 'django.middleware.csrf.CsrfViewMiddleware',

一、Django中CSRF中間件的工做原理及form表單提交須要添加{% csrf_token %}防止出現403錯誤
CSRF # 表示django全局發送post請求均須要字符串驗證
功能:防止跨站請求僞造的功能
工做原理:客戶端訪問服務器端,在服務器端正常返回給客戶端數據的時候,而外返回給客戶端一段字符串,等到客戶端下次訪問服務器
端時,服務器端會到客戶端查找先前返回的字符串,若是找到則繼續,找不到就拒絕。
訪問流程:客戶端-》URL路由系統 - 》 CSRF -》視圖函數
須要在客戶端頁面的post表單內添加:{% csrf_token %}
 全局生效:
  中間件 django.middleware.csrf.CsrfViewMiddleware
局部生效:
@csrf_protect,爲當前函數強制設置防跨站請求僞造功能,即使settings中沒有設置全局中間件。
@csrf_exempt,取消當前函數防跨站請求僞造功能,即使settings中設置了全局中間件。
寫法以下:
from django.views.decorators.csrf import csrf_exempt,csrf_protect
@csrf_exempt
def index(request): # 這樣表示此函數取消CSRF驗證

二、Django中使用ajax作post提交防止出現403錯誤的方法
 

如今以ajax發送一個請求,注意get和post的區別,post會被forbidden,get不會,html

 

url 文件前端

 
複製代碼
from django.conf.urls import url
from django.contrib import admin

from app01 import views

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^login/', views.login),
    url(r'^ajax_send/', views.ajax_send),
]
複製代碼
 

在views文件中,jquery

 
def ajax_send(request):


    return HttpResponse("ok")
 

在前端頁面,,ajax

 
複製代碼
{% load staticfiles %}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>

    <script src="{% static 'jquery-3.2.1.js' %}"></script>

</head>
<body>



<button>ajax發送</button>

</body>

<script>
    
    $("button").click(function () {

        $.ajax({
            url:"/ajax_send/",
            data:{"user":"gu"},
            type:"POST",  ----------若是以get請求是不會被forbidden,只有post請求會被forbidden,
            success:function (data) {
                alert(data)
            }

    })

    })

</script>


</html>
複製代碼
 

ajax的post請求會報錯,forbiddendjango

 
Forbidden (CSRF token missing or incorrect.): /ajax_send/
[10/Dec/2017 10:58:41] "POST /ajax_send/ HTTP/1.1" 403 2502
Forbidden (CSRF token missing or incorrect.): /ajax_send/
[10/Dec/2017 10:59:22] "POST /ajax_send/ HTTP/1.1" 403 2502
Forbidden (CSRF token missing or incorrect.): /ajax_send/
 

若是想要避免forbidden,瀏覽器

 

方法1:要在ajax發送請求前加上服務器

 
$.ajaxSetup({
data:{csrfmiddlewaretoken:'{{ csrf_token }}'},
});

注意:{{ csrf_token }} ,是須要渲染的,不能脫離模板,因此是外部文件引入的話,不能執行,
 
複製代碼
{% load staticfiles %}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>

    <script src="{% static 'jquery-3.2.1.js' %}"></script>

</head>
<body>


<button>ajax發送</button>

</body>

<script>
    
    $("button").click(function () {

        $.ajaxSetup({
            data:{csrfmiddlewaretoken:'{{ csrf_token }}'},---------
        });

        $.ajax({

            url:"/ajax_send/",
            data:{"user":"gu"},
            type:"POST",
            success:function (data) {
                alert(data)
            }

    })

    })
    


</script>


</html>
複製代碼
 
 
 

方法2:在ajax發送請求是加上csrfmiddlewaretoken,的值,cookie

 
複製代碼
        $.ajax({

            url:"/ajax_send/",
            data:{"user":"gu","csrfmiddlewaretoken":$("[name='csrfmiddlewaretoken']").val()},-----與方法1的功能同樣,
但這種方法能夠做爲一個外部文件引入, type:"POST", success:function (data) { alert(data) } }) })
複製代碼
 

-------session

 

 

 

 
 
 

 方法3:修改header,app

 

在views打印cookie能夠獲得csrftoken

 
複製代碼
def index(request):

    print("cookie",request.COOKIES)
    #cookie {
    # 'csrftoken': 'AB9v1MGTbdpSGg3FaGCIiUxrKVR8zKSqgdGFDn5E0ADsJ2ST7N2zgW6KboQ8G31x',
    # 'sessionid': 'eexw5p38vky9qo38nf372dz5lj1br6xf'
    # }
    #cookie 是瀏覽器給的,

    return HttpResponse("index")
複製代碼
 

 

 

須要先下載一個jquery.cookie.js插件文件,而後引用,

 
<script src="{% static 'jquery.cookie.js' %}"></script>

 
複製代碼
{% load staticfiles %}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>

{#    <script src="{% static 'jquery-3.2.1.js' %}"></script>#}
    <script src="{% static 'jquery.cookie.js' %}"></script>

</head>
<body>

{#<form action="/login/" method="post">#}
{# csrf_token 在前端會渲染出一個input標籤,是一組鍵值對,鍵是csrfmiddlewaretoken,值是隨機字符串,會隨着下面的input標籤一塊兒提交,只有這種形式發送post的請求才能被接收,#}
{##}
{#    {% csrf_token %}#}
{#    <p>用戶名:{{ form_obj.user }}</p>#}
{#    <p>密  碼:{{ form_obj.pwd }}</p>#}
{#    <input type="submit">#}
{##}
{#</form>#}

<button>ajax發送</button>

</body>

<script>
    
{#    $("button").click(function () {#}
{##}
{#        $.ajaxSetup({#}
{#            data:{csrfmiddlewaretoken:'{{ csrf_token }}'},#}
{#        });#}
{##}
{#        $.ajax({#}
{##}
{#            url:"/ajax_send/",#}
{#            data:{"user":"gu","csrfmiddlewaretoken":$("[name='csrfmiddlewaretoken']").val()},#}
{#            type:"POST",#}
{#            success:function (data) {#}
{#                alert(data)#}
{#            }#}
{##}
{#{)#}

$('button').click(function () {

        $.ajax({
        url:"/ajax_send/",
        type:"post",
        headers:{"X_CSRFToken":$.cookie('csrftoken')},---------------
        success:function () {
            alert(123)
        }

    })
})


    


</script>


</html>
複製代碼
 
 
 

-----

 

input 標籤的上傳文件,

 

在前端頁面

 
複製代碼
{#發送文件的時候,要加上enctype ,是以塊的方式發送文件,#}
<form action="/login/" method="post" enctype="multipart/form-data">
    <input type="file" name="fileobj">

</form>


<button>ajax發送</button>
複製代碼
 

在views文件中,獲取文件,保存文件,

 
 
 
複製代碼
def login(request):

    if request.method == "POST":


        print("post",request.POST.get("fileobj"))
        print("post",type(request.POST.get("fileobj")))
        print("===",request.FILES)

        fileobj = request.FILES.get("fileobj")

        #建立一個文件句柄,把文件存起來,
        f=open(fileobj.name,'wb')

        for i in fileobj.chunks():#按塊存
            f.write(i)
複製代碼
相關文章
相關標籤/搜索