今天重新认识了Post/Redirect/Get pattern, 感谢hip-hop的session, 一下帮助我理清了概念和思路.

谈到pattern,首先要清楚它为了什么而产生: PRG (参见链接1)是为了解决web页面的double submit问题而提供的一种方案.

1. double submit problem

上下文: 用户在browser中的pageA页面完成输入,点击了提交按钮,进入pageB页面,提示"提交成功". 这时, 若分别出现下列三种case:

1> 重新载入或刷新pageB;

2> 点击浏览器的后退按钮,接着点击前进按钮;

3> 点击浏览器的后退按钮退回到pageA,再点一回提交按钮;

对于没有考虑过这种问题而直接开发的网站,会出现什么情况呢?

case 1和case 2会由浏览器弹出一个小窗口,提示大意如"可能重复提交页面,是否继续?"的询问,如果选择了yes,那么前面的提交行为会再做一次;而case 3属于你主动地再一次提交. 也就是说,如果是买东西的话,那你已经重复买到了第二份! 这就是所谓的double submit.

究起实质, 是由于submit pageA和点击提交按钮共用了同一个服务器请求, 而这恰恰是一个POST请求, 在页面被重复提交的背后, POST请求也被多次发送, 导致server上错误地多次执行了添加或更改数据的行为. 图1解释了double submit问题.

图 1 Double Submit Problem

2. PRG solusion

应该想到,用户的这类如"后退再前进"或刷新的行为, 应当视为对历史结果或页面的查看, 并无再次提交之意.

解决问题的一种思路就是将用户点击提交按钮从而发出POST请求, 页面提交跳转和显示结果页面这三个行为分离开. PRG正是遵循这种思路, Client用POST方法请求Server响应数据变更, Server用Redirect方法将response指定到另一个URL上的结果页面, Client所有对页面显示的请求都用GET方法告知Server. 解决方案如图2所示. 这样, "后退再前进"或刷新页面的行为都发出的是GET请求, 从而不会对server产生任何数据更改的影响, double submit problem得以解决.

图2  PRG solusion

Basic principles:

* 不要用一个页面直接作为POST请求的响应结果, 你会给习惯"后退再前进"的人留下resubmit难题.

* 在处理完POST请求之后, redirect到另一个URL页面, 刷新页面的人就只能看到它.

* 用GET而不是POST去请求一个页面的显示, 当你需要的仅仅是显示的结果.

请注意:

* 后退到页面内再点击提交按钮来提交页面的行为,依然被认为是用户自愿的提交.

* 第一次提交后, Server的response正常完成之前的再次提交若未被所应用的框架阻止的话, 它会被Server认为是另一个正常提交.

3. IsPostBack

值得一提的是, .Net WebForm中, 常在Page_Load方法中使用Page.IsPostBack属性来判断对当前Form的请求是第一次or非第一次, 这和本文讨论的问题不完全一致: Asp.net提供了支持服务器端事件的控件, 同时还支持控件的AutoPostBack行为, 故会多次发出对当前Form的请求, 而IsPostBack提供了加载页面时的一个逻辑分支. IsPostBack属性在多种情况下的取值规则可参见链接2 .

附参考链接:

[1]  http://en.wikipedia.org/wiki/Post/Redirect/Get

[2]  http://www.cnblogs.com/hobe/archive/2008/04/06/1139031.html

http://blog.csdn.net/shaobo_wu/article/details/5854448

转---Post/Redirect/Get pattern的更多相关文章

  1. Post/Redirect/Get pattern | PRG 模式

    Post/Redirect/Get 是一种 web 开发设计模式,用于防止表单的重复提交. 默认情况,提交 Post 请求到服务器后,如果直接刷新浏览器,会重新在提交一次 Post 请求.在访问电商网 ...

  2. Go web开发初探

    2017年的第一篇博客,也是第一次写博客,写的不好,请各位见谅. 本人之前一直学习java.java web,最近开始学习Go语言,所以也想了解一下Go语言中web的开发方式以及运行机制. 在< ...

  3. A real ROCA using Bootstrap, jQuery, Thymeleaf, Spring HATEOAS and Spring MVC

    http://www.tuicool.com/articles/ENfe2u https://github.com/tobiasflohre/movie-database What is the be ...

  4. ASP.NET MVC:4 Ways To Prevent Duplicate Form Submission(转载)

    原文地址:http://technoesis.net/prevent-double-form-submission/. Double form submission in a multi-user w ...

  5. Go 源码学习之--net/http

    其实自己不是很会看源码,但是学习优秀的源码是提升自己代码能力的一种方式,也可以对自己以后写代码有一个很好的影响,所以决定在之后的时间内,要有一个很好的习惯,阅读优秀的源码.刚开始自己会觉得看源码很痛苦 ...

  6. Go Revel - Session / Flash(会话与flash)

    ##Session / Flash 作用域 revel提供了两种cookies存储机制: // 一个加密签过的cookie (限制为4kb). // 限制: Key 中不能有冒号 type Sessi ...

  7. springmvc DispatchServlet初始化九大加载策略(三)

    7. initRequestToViewNameTranslator 请求视图名 它主要与视图解析有关,如果对ViewResolvers.ModelAndView.View等没有多大印象,可以先看第8 ...

  8. Golang构建HTTP服务(一)--- net/http库源码笔记

    搭建一个简单的Go Web服务器 Go语言标准库 - net/http 在学习Go语言有一个很好的起点,Go语言官方文档很详细,今天我们学习的Go Web服务器的搭建就需要用到Go语言官方提供的标准库 ...

  9. Spring 4 官方文档学习(十一)Web MVC 框架之Flash Attributes

    接上一篇中的重定向. http://docs.spring.io/spring/docs/current/spring-framework-reference/html/mvc.html#mvc-fl ...

随机推荐

  1. 20155339《java程序设计》第一次实验报告

    20155339<java程序设计>第一次实验报告 实验一 java开发环境的熟悉 实验内容 1.使用JDK编译.运行简单的java程序: 2.使用IDEA编辑.编译.运行.调试java程 ...

  2. 思维水题 poj1852

    题目链接:http://poj.org/problem?id=1852 题意:木板长为n,    蚂蚁数量为k,    后面k个数,依次代表蚂蚁的位置,  当蚂蚁到达边界的时候会立马掉下,当两个蚂蚁相 ...

  3. Mac 用Ctr+C复制,Ctr+V 粘贴

    用习惯Windows的用户,进入Mac,不习惯快捷方式. 用下面的方法,可以返回windows 习惯. 1.进入系统偏好设置->键盘->修饰键 2.Control 选择 Command,C ...

  4. js灵活处理日期(函实例)

    基础方法: var dd = new Date() dd.getFullYear() dd.getMonth() dd.getDate() dd.getDay() //获取星期几(0~6) dd.ge ...

  5. 移动端推广APP防作弊机制之依我见

    本文来自网易云社区 在广告投放过程中,虚假流量常常给广告运营人员带来麻烦,影响广告投放的效果,如何预防作弊,不妨先来重现一下流量产生的场景,用户点击广告之后,一般都会落到广告主的网页,或者安装广告主的 ...

  6. 身份证扫描识别/身份证OCR识别的正确姿势,你get到了吗?

    自从国家规定电信实名制之后,实名制已经推广到各个领域:办理通信业务需要实名制.银行开户需要实名制.移动支付需要实名制,就连注册个自媒体账户都需要实名制. 而实名制的背后,就是身份证信息的采集和录入验证 ...

  7. Siki_Unity_2-7_Stealth秘密行动

    Unity 2-7 Stealth秘密行动 Abstract:向量运算:Animation动画:Navigation寻路系统:Mecanim动画系统 任务1&2&3:游戏介绍 & ...

  8. 4星|《亿万》:FBI大战华尔街对冲基金大鳄

    亿万:围剿华尔街大白鲨 全书尝试还原2008-2013年前后FBI指控赛克资本老板科恩通过内幕交易盈利的案件细节. 作者花了数年时间,采访了200多位当事人,阅读了海量的相关资料.书中交代了科恩的发家 ...

  9. SQL判断是否存在

    判断数据库是否存在 ifexists(select*frommaster..sysdatabaseswherename=N’库名’) print’exists’ else print’notexist ...

  10. react native中state和ref的使用

    react native中state和ref的使用 因props是只读的,页面中需要交互的情况我们就需要用到state. 一.如何使用state 1:初始化state 第一种方式: construct ...