1. 程式人生 > >django種表單post出現CSRF verification failed( CSRF驗證失敗 ) 的兩種解決方案

django種表單post出現CSRF verification failed( CSRF驗證失敗 ) 的兩種解決方案

現象

表單介面如下:


在點選提交之後,出現如下錯誤頁面:


HTML的程式碼如下:

contact_form.html

<!DOCTYPE HTML PUBLIC >

<html>
<head>
    <title>Contact us</title>
</head>

<body>
    <h1>Contact us</h1>
    {% if errors %}
       <ul>
          {% for error in errors %}
           <li>{{ error }}</li>
           {% endfor %}
       </ul>
    {% endif %}
    <form action="/contact/" method="post">
        <p>Subject: <input type="text" name="subject" value="{{ subject }}"></p>
        <p>Your e-mail (optional): <input type="text" name="email" value="{{ email }}"></p>
        <p>Message: <textarea name="message" rows="10" cols="50">{{ message }}</textarea></p>
        <input type="submit" value="Submit">
    </form>
</body>
</html>

view程式碼如下:

view.py

# -*- coding: utf-8 -*-

from django.core.mail import send_mail
from django.http import HttpResponseRedirect
from django.shortcuts import render_to_response

def contact(request):
    errors = []
    if request.method == 'POST':
        if not request.POST.get('subject', ''):
            errors.append('Enter a subject.')
        if not request.POST.get('message', ''):
            errors.append('Enter a message.')
        if request.POST.get('email') and '@' not in request.POST['email']:
            errors.append('Enter a valid e‐mail address.')
        if not errors:
            send_mail(
                      request.POST['subject'],
                      request.POST['message'],
                      request.POST.get('email', '
[email protected]
'), ['[email protected]'], ) return HttpResponseRedirect('/contact/thanks/') return render_to_response('contact_form.html', { 'errors': errors, 'subject': request.POST.get('subject', ''), 'message': request.POST.get('message', ''), 'email': request.POST.get('email', ''), })

一般瀏覽器都是開啟了cookies的,所以在上面圖中的錯誤資訊中,我們主要關注後三點,根據提示進行更改:

解決方案一:CSRF驗證設定

1. 在 view.py 中的 render_to_response 中,使用 RequestContext 來代替預設的 Context 。

view.py

# -*- coding: utf-8 -*-

from django.core.mail import send_mail
from django.http import HttpResponseRedirect
from django.shortcuts import render_to_response
from django.template import RequestContext

def contact(request):
    errors = []
    if request.method == 'POST':
        if not request.POST.get('subject', ''):
            errors.append('Enter a subject.')
        if not request.POST.get('message', ''):
            errors.append('Enter a message.')
        if request.POST.get('email') and '@' not in request.POST['email']:
            errors.append('Enter a valid e‐mail address.')
        if not errors:
            send_mail(
                      request.POST['subject'],
                      request.POST['message'],
                      request.POST.get('email', '[email protected]'),
                      ['[email protected]'],
                      )
            return HttpResponseRedirect('/contact/thanks/')
    return render_to_response('contact_form.html', {
                                                    'errors': errors,
                                                    'subject': request.POST.get('subject', ''),
                                                    'message': request.POST.get('message', ''),
                                                    'email': request.POST.get('email', ''),
                                                    },context_instance=RequestContext(request))

2. 在模板檔案中的 form 表單內新增 {% csrf_token %} 。

contact_form.html

<!DOCTYPE HTML PUBLIC >

<html>
<head>
    <title>Contact us</title>
</head>

<body>
    <h1>Contact us</h1>
    {% if errors %}
       <ul>
          {% for error in errors %}
           <li>{{ error }}</li>
           {% endfor %}
       </ul>
    {% endif %}
    <form action="/contact/" method="post">
        <br />{% csrf_token %}<br />
        <p>Subject: <input type="text" name="subject" value="{{ subject }}"></p>
        <p>Your e-mail (optional): <input type="text" name="email" value="{{ email }}"></p>
        <p>Message: <textarea name="message" rows="10" cols="50">{{ message }}</textarea></p>
        <input type="submit" value="Submit">
    </form>
</body>
</html>

測試執行,成功!

PS:上文中圖片中的錯誤資訊第四條,在建立django工程的時候 setting.py 已經自動添加了 'django.middleware.csrf.CsrfViewMiddleware',

MIDDLEWARE_CLASSES = (
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    'django.middleware.security.SecurityMiddleware',
    'django.middleware.locale.LocaleMiddleware',
)


解決方案二:不使用 CSRF 驗證

1. 在 setting.py 檔案中刪除  'django.middleware.csrf.CsrfViewMiddleware', ,如下所示

MIDDLEWARE_CLASSES = (
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    #'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    'django.middleware.security.SecurityMiddleware',
    'django.middleware.locale.LocaleMiddleware',
)

2. 移除 form 表單中的  {% csrf_token %} 標記。如下所示:

contact_form.html

<!DOCTYPE HTML PUBLIC >

<html>
<head>
    <title>Contact us</title>
</head>

<body>
    <h1>Contact us</h1>
    {% if errors %}
       <ul>
          {% for error in errors %}
           <li>{{ error }}</li>
           {% endfor %}
       </ul>
    {% endif %}
    <form action="/contact/" method="post">
        <p>Subject: <input type="text" name="subject" value="{{ subject }}"></p>
        <p>Your e-mail (optional): <input type="text" name="email" value="{{ email }}"></p>
        <p>Message: <textarea name="message" rows="10" cols="50">{{ message }}</textarea></p>
        <input type="submit" value="Submit">
    </form>
</body>
</html>

3. 在 view.py 中的 render_to_response 中,不使用 RequestContext 。如下所示:

view.py

# -*- coding: utf-8 -*-

from django.core.mail import send_mail
from django.http import HttpResponseRedirect
from django.shortcuts import render_to_response
from django.template import RequestContext

def contact(request):
    errors = []
    if request.method == 'POST':
        if not request.POST.get('subject', ''):
            errors.append('Enter a subject.')
        if not request.POST.get('message', ''):
            errors.append('Enter a message.')
        if request.POST.get('email') and '@' not in request.POST['email']:
            errors.append('Enter a valid e‐mail address.')
        if not errors:
            send_mail(
                      request.POST['subject'],
                      request.POST['message'],
                      request.POST.get('email', '[email protected]'),
                      ['[email protected]'],
                      )
            return HttpResponseRedirect('/contact/thanks/')
    return render_to_response('contact_form.html', {
                                                    'errors': errors,
                                                    'subject': request.POST.get('subject', ''),
                                                    'message': request.POST.get('message', ''),
                                                    'email': request.POST.get('email', ''),
                                                    })

重新執行,測試成功!

相關推薦

djangopost出現CSRF verification failed( CSRF驗證失敗 ) 的解決方案

現象 表單介面如下: 在點選提交之後,出現如下錯誤頁面: HTML的程式碼如下: contact_form.html <!DOCTYPE HTML PUBLIC > <html> <head> <title&g

Django提交時遇到403錯誤:CSRF verification failed

在學習Django框架提交表單時,遇到了403錯誤,詳細資訊如下: Forbidden (403) CSRF verification failed. Request aborted. You are seeing this message because this si

提交資料,在IE及其它瀏覽器中亂碼的解決方案

如在IE下提交表單資料亂碼:        解決方案: 在form表單中新增    onsubmit="document.charset='GBK';"       【注編碼根據各自環境條件指定】 如在其它瀏覽器下提交表單資料亂碼:            acce

python3.6安裝pyspider出現的問題(pycurl安裝失敗)和解決方案

使用pip install pyspider 發現安裝失敗 圖片一 於是上網查了一下原因是因為安裝pyspider之前需要安裝lxml 和 pycurl ,但是在安裝pycurl的過程中遇到了同樣的錯誤 解決方案是安裝wheel 和到 http://www.lfd.uci.

【SSH框架】生成JSON的個典型問題:1.使用jsonlib工具獲取關聯屬性失敗。2.獲取關聯屬性出現遞迴導致獲取JSON失敗。附解決方案

問題1原因:hibernate中的物件的關聯屬性預設都是懶載入的,而使用jsonlib這個工具類是通過反射去獲取物件中的關聯屬性的,和我們通過後臺直接獲取的方式不同,通過後臺直接獲取管理屬性會讓hibe

django post提交資料出現403錯誤解決

解決辦法是:在檢視檔案views.py裡面使用@csrf_exempt 或者在setting.py裡面註釋掉CSRF那一行 出現這個錯誤的原因主要是,跨站請求偽造。 簡單來說就是,django框架為我們提供了一箇中間件,用於處理跨站請求偽造

瀏覽器原生 form POST 數據的方式

mes 但是 lba lose -s ipa mvm 默認 字串 我們在提交表單的時候,form表單參數中會有一個enctype的參數。enctype指定了HTTP請求的Content-Type。 常用有兩種:application/x-www-form-urlencod

CSRF verification failed 報錯的解決

如果你第一次用表單提交資料,很可能會遇到這麼一個報錯:CSRF verification failed. Request aborted. 這個問題如何解決呢? 1. 在表單里加上{% csrf_token %}。 根據提示 In the template, the

get和post提交方式的區別

角色 編碼方式 不同 面試官 qpi 但是 優化 method log 今天看到一篇博客談論get和post區別,簡單總結一下https://www.cnblogs.com/logsharing/p/8448446.html 要說兩者的區別,接觸過web開發的人基本上都能說

django-25.提交之post註冊案例

ddl comm 指向 註冊 跳轉 避免 ring put n) 一個網站上新用戶註冊,會寫個註冊頁面,如果用django寫個註冊頁面的流程呢?本篇以post請求示例,從html頁面上輸入用戶註冊信息,提交到後臺處理數據,然後傳參數據到User數據庫表裏面 註冊頁

django系統

mes 都是 value sub val 實例 userinfo 需要 展示 1、概述: django表單系統中,自定義表單類都是以django.forms.Form為父類進行創建; django中的Form一般有兩種功能: 生成特定的HTML標簽 後臺驗證用戶提交的數據

django form驗證

錯誤 mail 定義 lap hide else ren end blog 簡單例子: 1 #自定義驗證類 2 class Check_form1(forms.Form): 3 #user就是要驗證的字段,這裏對應前端name <inp

Django-form

gist 第一個 例子 構建 ole 最短 輸入 his 用戶 構建一個表單 假設你想在你的網站上創建一個簡單的表單,以獲得用戶的名字。你需要類似這樣的模板: ? 1 2 3 4 5 <form ac

jQuery使用serialize(),serializeArray()方法取得單數據+字符串和對象類型提交的方法

var fun .ajax clas copy art 表單提交 post 姓名 轉載自: http://blog.csdn.net/zqtsx/article/details/28655717 原始form表單值獲取方式(手動): [javascript] v

Django---Form

pat space ipad you except forms 模塊 子類 幫助信息 form組件的特點 數據的重置 校驗規則 程序執行文件, sys.path ,加載當前文件的路徑,到內存中,會執行當前文件。 在當前的sys.path 環境中查找該文件,找不到就會

Django form

max 移除 ipad container led true image 雙色球 clas Form介紹 我們之前在HTML頁面中利用form表單向後端提交數據時,都會寫一些獲取用戶輸入的標簽並且用form標簽把它們包起來。 與此同時我們在好多場景下都需要對用戶的輸入做校

六、Django和類視圖-Part 4

true abs 不能 註意 自動跳轉 請求偽造 mes direct base 一、表單form 為了接收用戶的投票選擇,我們需要在前端頁面顯示一個投票界面。讓我們重寫先前的polls/detail.html文件,代碼如下: <h1>{{ question.q

django form 驗證

nbsp 驗證 bsp com img 表單驗證 png 表單 djang django form 表單驗證

Vue中axios POST提交

剛開始使用Vue,裡面的坑是一個接一個,今天就遇到一個axios POST傳參的問題。 因為後端要求是按表單提交的形式給他資料, 我需要在請求中傳遞引數,然後按官方文件的格式開始操作,程式碼如下: axios.post('/user', {   &nbs

015---Django的forms元件 Django form

Django form表單   Form介紹  我們之前在HTML頁面中利用form表單向後端提交資料時,都會寫一些獲取使用者輸入的標籤並且用form標籤把它們包起來。 與此同時我們在好多場景下都需要對使用者的輸入做校驗,比如校驗使