部落格轉載請註明出處!
作者:羽龍飛
原文連結:http://blog.csdn.net/zgyulongfei/article/details/8830750
先讓我還原一下錯誤頁面:
今天被這個錯誤折騰了一上午,搞得我心力交瘁。網上搜尋了很多答案,大致解決方案都是相同,我照著做,可是錯誤依然存在。
後來找jack幫忙才總算解決了這個問題。
原來我之前的方案一直是本末倒置,沒有摸清楚django的csrf原理,就在那邊瞎弄,浪費了很多時間。
下面我來說說我問題所在,如果你和我犯了同樣的錯誤,可以做一下參考。
首先我做了一個test.html,如下:
<!DOCTYPE><html lang="zh-CN"> <head> <meta charset="utf-8"> <title> test </title> </head> <body> <form action="/postblog" method="post"> {% csrf_token %} <input type="text" name="blog" /> <input type="submit" value="發布" /> </form> </body></html>
訪問時候為 xx.xx.com/post,執行的方法為
def post_html(rq):return render_to_response("test.html")
這個表單中已經包含了tag {% csrf_token %},這是網上解決方案中都說需要加上的標籤。
點擊【發布】按鈕提交表單之後,執行/postblog操作,接下來看看服務端代碼。
先在settings.py中加上
django.middleware.csrf.CsrfViewMiddleware
MIDDLEWARE_CLASSES = ( 'django.middleware.common.CommonMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', # Uncomment the next line for simple clickjacking protection: # 'django.middleware.clickjacking.XFrameOptionsMiddleware',)
再看urls.py
url(r'^postblog$','postBlog')
然後看views.py
def postBlog(rq):return render_to_response('ok.html', context_instance=RequestContext(rq))
對於一個django初學者來說,一切都按照錯誤頁面的Help中來做的啊,為什麼結果還是錯誤的呢?
答:因為,,,從一開始的html頁面就錯了,而我在錯誤的前提下去做結果的補救,就救不回來了←_←
有經驗的django開發人員應該一眼就看得出錯誤的根源。
其實表單中的{% csrf_token %}在html頁面被載入的時候就已經被賦值了,而post的時候需要將這個被賦值的csrf_token發送給服務端進行驗證,如果驗證成功才能進行post操作,否則就被認為是csrf攻擊。
而上文中的test.html中一開始並沒有由伺服器給出一個csrf_token,在post的時候自然而然就不能成功驗證。
而 context_instance=RequestContext(rq)的作用就是給這個csrf_token進行賦值,上文中卻把賦值的操作在post之後進行,而正確地操作是在post之前開啟html頁面的時候就賦值。
所以只要修改post_html方法就行:
def post_html(rq):return render_to_response("test.html",context_instance=RequestContext(rq))
以上。