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', ''),
                                                    })

重新运行,测试成功!

时间: 2025-01-10 08:15:24

django种表单post出现CSRF verification failed( CSRF验证失败 ) 的两种解决方案的相关文章

Django POST CSRF verification failed. Request abor

环境 Window 7 Python2.7 Django1.4.1 sqlite3 问题 在使用Django搭建好测试环境后,写了一个提交POST表单提交留言的测试页面. 如图: 填写表单,点击“提交留言”按钮提交到服务器,却出现 Forbidden (403) CSRF verification failed. Request aborted. 由于之前使用GET方式提交表单内容测试均正常,就以为这个问题估计是配置问题没细看后边的帮助提示直接在网上搜索解决方案. 一搜索发现相关网页很多,看来大

Django之七表单

前言 从Google的简朴的单个搜索框,到常见的Blog评论提交表单,再到复杂的自定义数据输入接口,HTML表单一直是交互性网站的支柱. 本节介绍如何用Django对用户通过表单提交的数据进行访问.有效性检查以及其它处理. 与此同时,我们将介绍HttpRequest对象和Form对象. 从Request对象种获取数据 我们在第三节讲述View的函数时已经介绍过HttpRequest对象了,但当时并没有讲太多. 让我们回忆下:每个view函数的第一个参数是一个HttpRequest对象,就像下面这

Django提交POST表单“CSRF verification failed. Request aborted”问题的解决

1.环境 python 3.4 Django 1.7 Visual Studio 2015 PTVS 2.问题 提交表单,出现以下错误: CSRF verification failed. Request aborted. 3.解决 查看settings.py, 有 'django.middleware.csrf.CsrfViewMiddleware' 一句: 1 MIDDLEWARE_CLASSES = ( 2 'django.contrib.sessions.middleware.Sessi

向Django提交表单

Python的django框架,做了一个前端页面,其中有一向要求提交表单,暂且总结一下流程,有不对的地方请指正: 1.在HTML页面写表单: <form enctype="multipart/form-data" method="POST" action="{% url 'upload' %}"> {% csrf_token %} <input type="file" name="your_file

django的表单系统

1.概述: django表单系统中,自定义表单类都是以django.forms.Form为父类进行创建: django中的Form一般有两种功能: 生成特定的HTML标签 后台验证用户提交的数据 2.在views文件中自定义form表单类: # 自定义form表单类 class Userinfo(forms.Form): name = forms.CharField() password = forms.CharField() email = forms.EmailField() message

Django Form表单

Django  Form 表单 在实际的生产环境中比如登录和验证的时候,我们一般都使用Jquery+ajax来判断用户的输入是否为空,假如JS被禁用的话,咱们这个认证屏障是不是就消失了呢?(虽然一般不会禁用掉但是还是存在风险) 所以我们一般做两种认证一种是前端做一遍认证,在后端做一遍认证. 首先咱们看一下下面的案例: from django.shortcuts import render # Create your views here. def user_list(request): host

四种表单验证方法的分析和比较

前言 任何可以交互的站点都有输入表单,只要有可能,就应该对用户输入的数据进行验证.无论服务器后端是什么样的系统,都不愿意把时间浪费在一些无效的信息上,必须对表单数据进行校验,若有不符合规定的表单输入,应及时返回并给出相应的提示信息.本文将列举四种不同原理的表单验证方法,并给出各方法在 PHP 服务器上的实现. 回页首 浏览器端验证 传统上,表单数据一般都通过浏览器端的 Javascript 验证.浏览器端的验证速度快,若有不符合要求的输入,响应信息快速的返回给用户.由于验证数据不需要提交给服务器

Node.JS的表单提交及OnceIO中接受GET/POST数据的三种方法

OnceIO 是 OnceDoc 企业私有内容(文档)管理系统的底层Web框架,它可以实现模板文件.静态文件的全缓存,运行起来完全不需要I/O操作,并且支持客户端缓存优化,GZIP压缩等(只压缩一次),拥有非常好的性能,为您节约服务器成本.它的模块化功能,可以让你的Web进行分布式存储,在一个扩展包里即可包含前端.后端和数据库定义,只需通过添加/删除目录的方式就可实现功能删减,实现真正的模块化扩展.目前 OnceIO 已经开源,本文主要介绍node.js语言中的表单提交及OnceIO中接受GET

jQuery使用serialize(),serializeArray()方法取得表单数据+字符串和对象类型两种表单提交的方法

原始form表单值获取方式(手动): $.ajax({ type: "POST", url: "ajax.php", data: "Name=摘取天上星&position=IT技术", success: function(msg){alert(msg);}, error: function(error){alert(error);} }); JQ serialize()方法取值: $.ajax({ type: "POST&quo