Django框架开发中避免表单重复提交

简介:

 Form表单做为web2.0时代的重要角色,也是我们与web网站进行数据交互的重要渠道,但是大家在web网站开发过程中,都会遇到一个问题,那就是如何避免表单重复提交,我们可不确定用户可在提交了一个表单后,是否有足够的耐心等待我们的程序加载完成,如果此时用户不耐烦的在前台重复刷新页面,那么就会造成数据重复提交、信息不准确,因此我们在程序设计时一定要规避这样的问题,接下来介绍一下在Django框架开发中如何避免此问题。

首先说明一下Http协议中两种非常常见的方法GET和POST。

1、GET方法往往被视为向服务器索取信息的一种手段,但是通过使用"?"和"&"符号也可以将不同的表单项提交给服务器,例如"/test?id=1"中我们就将id=1提交给了后台,有时在一些特殊情况中,我们甚至不需要在html中写form表单,只要我们保证url正确就可以了,但是使用GET方式提交也有一个问题需要注意,IE对于URL长度的限制是2083个字节,其他浏览器或是web server都有不同的限制,所以在提交较长的内容时,GET方法就有些不合适了。

2、POST方法相比GET方法在数据提交上更安全一些,因为GET方法将参数统一放到了URL中,随后在HTTP包头中发向服务器,但是提交的参数也就无疑被暴露了,在浏览器中可以直观的看到提交的具体内容,在web server中也可以通过访问日志随便查看提交的内容,对于有安全性的数据一定是采用POST方式来提交的,同时对于密码等敏感内容也一定要做加密处理,采用POST方法对于数据内容理论上也没有长度限制,这样就可以提交更多的数据内容了。

  使用POST方法提交表单往往可以增加信息传输的安全性,如果表单项过多也避免了较长的url,因此在web开发中我更喜欢用POST方法,回到之前的问题,就是页面提交过后,此时如果刷新页面,那么浏览器会提示重新提交表单,此时如果我们点击继续后,那么浏览器就会将之前提交过的内容再次发送至服务器,如果我们在后台没有做限制处理,那么数据就被重复提交了,试想一下如果A用户要转账给B用户,A用户输入转账金额2000元,在表单提交后,后台根据A用户发送的请求在数据库里更新A账户信息,如果此时A用户重复刷新页面,那么后台岂不是要连续的从A用户里扣除2000元增加到B用户中么,虽然现实生活中不可能发生这样的事情,但是这样却很好的说明了表单重复提交的危险性,因此对于POST方法提交表单,我们可以用下面的方式来避免重复提交。

1、URL重定向

  这种方式较为简单,我们可以在用户提交的表单后,在提交页面做一个读秒的倒计时提示,这也是我们在大多数网站上经常见到的,在倒计时结束后,页面被重新定向到上一级页面,或是我们希望被跳转的页面,这样在一定程度上就避免了重复刷新带来的风险,或是在页面提交后直接进行URL重定向,在Django的视图中我们可以使用HttpResponseRedirect来重定向页面。

2、Cookie验证

  上面的方式我们通过页面来进行控制,也就是说提交过后页面url放生了变化,此时用户再次刷新时就不会请求之前提交的页面,除了URL重定向,我们也可以通过cookie中key-value来做进一步限制,首先进入提交页前我们在cookie中写入一个值,在提交过后重置该值,这样后台通过获取cookie中的值就可以做判断了,此时如果用户再次刷新页面时,就可以返回提示说明信息已经提交过,不需要重复提交,在django框架中的代码如下。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 表单视图
def  page(request):
     response  =  render_to_response( 'post.html' )
     # 在客户端Cookie中添加Post表单token,避免用户重复提交表单
     response.set_cookie( "postToken" ,value = 'allow' )
     return  response
  
#提交视图
def  post(request):
     # 检测Token值,判断用户提交动作是否合法
     if  request.COOKIES[ "postToken" ] ! = 'allow' :
         # 不存在合法Token,该表单为重复提交
         return  HttpResponse( "you can't post it again." )
     '''
     代码逻辑处理段
     '''
     response  =  render_to_response( 'newPage.html' )
     # 表单POST提交成功,重置客户端Cookie中存在的Token值,避免重复提交
     response.set_cookie( "postToken" ,value = 'disable' )
     return  response

3、Hidden属性的隐藏域

  上一种方式我们在用户的浏览器中写入了指定的token值,我们也可以在服务器的session会话中写入特定的信息,然后将内容渲染到html页面中表单的隐藏域,用户从页面中是看不到这个隐藏域的,一般有特殊信息提交时会用到,比如这里的重复提交验证,我们就可以用表单的Hidden这个属性,我们将服务器生成的值写入到表单,随用户操作一起提交回服务器,那么如果该值与服务器端匹配,程序继续执行,否则认为重复提交,这里要注意与cookie操作中一样,我们在提交完后,服务器一定要清空session中的值。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 表单视图
def  page(request):
     # 在服务端session中添加key认证,避免用户重复提交表单
     token  =  allow  # 可以采用随机数
     request.session[ 'postToken' =  token
     # 将Token值返回给前台模板
     return  render_to_response( 'post.html' , 'postToken' :token)
  
#提交视图
def  post(request):
     # 检测session中Token值,判断用户提交动作是否合法
     Token  =  request.session.get(postToken,default = None )
     # 获取用户表单提交的Token值
     userToken  =  request.POST[ 'postToken' ]
     if   userToken ! = Token:
         # 不存在合法Token,该表单为重复提交
         return  HttpResponse( "you can't post it again." )
     '''
     代码逻辑处理段
     '''
     # 表单POST提交成功,重置服务端中存在的Token值,避免重复提交
     del  request.session[ 'postToken' ]
     return  render_to_response( 'newPage.html' )

4、验证码

  我们可以在表单页中加入验证码,每次提交时服务端来做验证,但是这样的方式又影响了提交操作的便捷度,有得有失。

对于GET的提交方式较为简单,在提交后重新定义url地址就可以了,因为url中没有了参数,也就避免了重复提交,但是为了避免用户重新访问之前的url地址,我们也可以结合上面的方法来对GET方法进行限制。

写在最后

  对于表单重复提交的情况,我们发现往往最容易出现在表单页与提交页URL相同、或是页面提交后依然停留在提交页URL中,在Django框架中,我认为表单页与提交页应该尽量使用不同的URL,不同的视图,这样我们可以更好的避免该问题,例如在提交后我们将URL重定向到表单页,甚至可以在前台使用Ajax异步来提交数据,这样提交动作不会影响到页面变化,用户再次刷新也只能刷新当前的表单页了。相信在web程序开发中一定还有更多种方法来规避表单重复提交的问题,这里所展示的也不一定是最完整准确的,但在web程序开发中我们一定要考虑到类似这样的异常,这才是最重要的。

原创文章首发自阿布的博客,本文地址:http://www.abuve.com/article/17/





     本文转自阿布ve 51CTO博客,原文链接:http://blog.51cto.com/abuve/1695975
,如需转载请自行联系原作者


相关文章
|
19天前
|
数据采集 中间件 Python
如何在Django框架中进行输入验证和过滤?
通过综合运用这些方法,可以在 Django 框架中有效地进行输入验证和过滤,提高应用的安全性和数据质量。同时,还可以根据具体的业务需求进一步扩展和定制验证逻辑。
102 64
|
28天前
|
开发者 数据库管理 Python
Django框架和Flask框架的区别
总体而言,Django 适合需要快速搭建大型应用的开发者,而 Flask 则更适合有特定需求和追求灵活性的开发者。
112 64
|
1月前
|
设计模式 前端开发 数据库
Python Web开发:Django框架下的全栈开发实战
【10月更文挑战第27天】本文介绍了Django框架在Python Web开发中的应用,涵盖了Django与Flask等框架的比较、项目结构、模型、视图、模板和URL配置等内容,并展示了实际代码示例,帮助读者快速掌握Django全栈开发的核心技术。
171 45
|
19天前
|
监控 安全 测试技术
Django框架的表单验证和过滤机制是否可以应对复杂的安全场景?
综上所述,Django 框架的表单验证和过滤机制在一定程度上可以应对复杂的安全场景,但需要综合运用多种手段来进一步提升安全性,以适应不断变化的安全挑战。
27 1
|
26天前
|
搜索推荐 API 开发者
Django框架和Flask框架的适用场景分别是什么?
总体而言,Django 更适合需要全面功能和大规模开发的场景,而 Flask 则更适合灵活性要求高、小型项目或特定需求的开发。当然,具体的选择还应根据项目的具体情况、团队的技术能力和偏好等因素来综合考虑。在实际应用中,开发者可以根据项目的特点和需求,灵活选择使用这两个框架,或者结合它们的优势来构建更强大的 Web 应用程序。
|
26天前
|
开发框架 搜索推荐 数据可视化
Django框架适合开发哪种类型的Web应用程序?
Django 框架凭借其强大的功能、稳定性和可扩展性,几乎可以适应各种类型的 Web 应用程序开发需求。无论是简单的网站还是复杂的企业级系统,Django 都能提供可靠的支持,帮助开发者快速构建高质量的应用。同时,其活跃的社区和丰富的资源也为开发者在项目实施过程中提供了有力的保障。
|
28天前
|
安全 前端开发 数据库
Django框架
总的来说,Django 是一个非常优秀的 Web 框架,它为开发者提供了坚实的基础和丰富的功能,使得构建高质量的 Web 应用变得更加容易和高效。无论是初学者还是经验丰富的开发者,都可以从中受益,利用它来实现自己的创意和想法。
40 4
|
1月前
|
Python
Django 框架的路由系统
Django 框架的路由系统
44 6
|
1月前
|
安全 数据库 开发者
Python Web开发:Django框架下的全栈开发实战
【10月更文挑战第26天】本文详细介绍了如何在Django框架下进行全栈开发,包括环境安装与配置、创建项目和应用、定义模型类、运行数据库迁移、创建视图和URL映射、编写模板以及启动开发服务器等步骤,并通过示例代码展示了具体实现过程。
59 2
|
7月前
|
开发框架 中间件 数据库
Django 框架入门全攻略:轻松构建 Web 应用
【5月更文挑战第18天】本文是 Django 入门教程,介绍了如何使用 Django 构建 Web 应用。内容包括安装、项目与应用创建、模型定义、数据库迁移、视图编写、路由配置、模板系统、表单处理和中间件的使用。通过实例展示了 Django 基本流程,帮助初学者快速上手。Django 提供高效工具,便于开发者聚焦业务逻辑,轻松构建功能丰富的 Web 应用。
110 5