转---Post/Redirect/Get pattern
今天重新认识了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的更多相关文章
- Post/Redirect/Get pattern | PRG 模式
Post/Redirect/Get 是一种 web 开发设计模式,用于防止表单的重复提交. 默认情况,提交 Post 请求到服务器后,如果直接刷新浏览器,会重新在提交一次 Post 请求.在访问电商网 ...
- Go web开发初探
2017年的第一篇博客,也是第一次写博客,写的不好,请各位见谅. 本人之前一直学习java.java web,最近开始学习Go语言,所以也想了解一下Go语言中web的开发方式以及运行机制. 在< ...
- 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 ...
- 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 ...
- Go 源码学习之--net/http
其实自己不是很会看源码,但是学习优秀的源码是提升自己代码能力的一种方式,也可以对自己以后写代码有一个很好的影响,所以决定在之后的时间内,要有一个很好的习惯,阅读优秀的源码.刚开始自己会觉得看源码很痛苦 ...
- Go Revel - Session / Flash(会话与flash)
##Session / Flash 作用域 revel提供了两种cookies存储机制: // 一个加密签过的cookie (限制为4kb). // 限制: Key 中不能有冒号 type Sessi ...
- springmvc DispatchServlet初始化九大加载策略(三)
7. initRequestToViewNameTranslator 请求视图名 它主要与视图解析有关,如果对ViewResolvers.ModelAndView.View等没有多大印象,可以先看第8 ...
- Golang构建HTTP服务(一)--- net/http库源码笔记
搭建一个简单的Go Web服务器 Go语言标准库 - net/http 在学习Go语言有一个很好的起点,Go语言官方文档很详细,今天我们学习的Go Web服务器的搭建就需要用到Go语言官方提供的标准库 ...
- Spring 4 官方文档学习(十一)Web MVC 框架之Flash Attributes
接上一篇中的重定向. http://docs.spring.io/spring/docs/current/spring-framework-reference/html/mvc.html#mvc-fl ...
随机推荐
- 【转载】值得推荐的C/C++框架和库
原文:值得推荐的C/C++框架和库 值得学习的C语言开源项目 Libevent libev是一个开源的事件驱动库,基于epoll,kqueue等OS提供的基础设施.其以高效出名,它可以将IO事件,定时 ...
- 1130: [POI2008]POD Subdivision of Kingdom
1130: [POI2008]POD Subdivision of Kingdom https://lydsy.com/JudgeOnline/problem.php?id=1130 分析: 有效状态 ...
- vue 3.0使用 BUG解决
最近在做vue的项目,吊进了很多坑,这些坑很浅,但一旦掉进去了,不花点功夫还爬不出来.所以总结下,当做下笔记,持续更新 1.<router-link> 里加的事件没反应 错误代码: < ...
- [WC2010]重建计划 长链剖分
[WC2010]重建计划 LG传送门 又一道长链剖分好题. 这题写点分治的人应该比较多吧,但是我太菜了,只会长链剖分. 如果你还不会长链剖分的基本操作,可以看看我的长链剖分总结. 首先一看求平均值最大 ...
- equals和==方法比较(二)--Long中equals源码分析
接上篇,分析equals方法在Long包装类中的重写,其他类及我们自定义的类,同样可以根据需要重新equals方法. equals方法定义 equals方法是Object类中的方法,java中所有的对 ...
- Android 8.0 NavigationBar 颜色问题。
1. packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarController.java public void on ...
- CentOS7使用阿里源安装最新版Docker
卸载已经安装的Docker sudo yum remove docker \ docker-client \ docker-client-latest \ docker-common \ docker ...
- NUMA 体系架构
NUMA 体系架构 SMP 体系架构 NUMA 体系架构 NUMA 结构基本概念 Openstack flavor NUMA 策略 Nova 实现 NUMA 流程 1. SMP 体系架构 CPU 计算 ...
- python错误记录
在主函数里调用其他函数时形参顺序要一致 错例如下:
- python循环结构
while循环 while 条件表达式: 语句块 while语句的条件表达式是循环条件,常用的是关系表达式或者逻辑表达式,语句块是循环执行的语句. n=1 p=1 num=int(input(&quo ...