关于防重复提交出现 页面过期的问题

在做包剪锤游戏时,下注的时候提交一个json 请求。不断的刷新后,点击下注,提示页面过期。

经分析研究有如下疑问:

1.页面已经产生了新的token, 点击下注按钮 ,匹配session中的token,发现找不到了token的值,提示页面已经过期,请刷新。

2.右键刷新之后,为何也没有产生新的token 值。
3.测试发现在地址栏直接回车或者CRAT + F5 强制刷新,可以产生新的token。而右键刷新不能产生新的token。地址栏刷新和F5 刷新的区别?

  • 关于第一点还是无法解决。

          当加载页面时,会根据页面的需要防重复提交的宏定义生成token值,如果有5个需要防重复提交,便会产生五个token。服务器将会把这五个token 放入session。用户点击提交按钮便会把当前的token与session的值匹对,如果在session中存在,说明是第一次提交,合法提交。这时页面上将会产生新的token。

  • 第二点的解决方案是将生成token的隐藏域更改如下:
<input type="hidden" autocomplete="off" value="$!tamperProofForm.token" id="$!tokenKey" name="$!tokenKeyName" />

添加了 autocomplete="off"

查看得知 此可以使当前的input属性的缓存失效,故每次请求都是新的value值。

如许,就能阻拦Firefox的默认缓存机制了。刷新之后,这些input的值都初始化。

还有一个写法,可以把全个表单中所有input都设置为不缓存的

有关解释:

input 的属性autocomplete 默认为on

其含义代表是否让浏览器自动记录之前输入的值

很多时候,需要对客户的资料进行保密,防止浏览器软件或者恶意插件获取到

可以在input中加入autocomplete="off" 来关闭记录

系统需要保密的情况下可以使用此参数

  • 关于第三点:

不少同学问,不都是刷新吗?还有什么区别?其实,还是有的。

其中,在地址栏按回车又分为两种情况。一是请求的URI在浏览器缓存中未过期,此时,使用Firefox的firebug插件在浏览器里显示的HTTP请求消息头如下:

Host    192.168.3.174:8080

User-Agent    Mozilla/5.0 (Windows NT 5.1; rv:5.0) Gecko/20100101 Firefox/5.0

Accept    text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8

Accept-Language    zh-cn,zh;q=0.5

Accept-Encoding    gzip, deflate

Accept-Charset    GB2312,utf-8;q=0.7,*;q=0.7

Connection    keep-alive

HTTP返回状态显示2

00 OK,但是,后台Nginx服务器的access.log并没有找到该请求的记录,说明请求并没有真正提交到HTTP服务器。而是被浏览器发现缓存中还有未过期的文件,直接把请求拦截了,firebug里面显示所谓的“请求头消息”、“响应头消息”都是浏览器“伪造”的。这种刷新,使用的网络流量是最小的,可以说完全没有,时间消耗也是最少的。就像你找到一盒没有过期的牛奶,觉得肯定没有问题,谁都没告诉就喝了。

二是请求的URI在浏览器缓存中已过期,此时,firebug显示的HTTP请求消息头如下:

Host    192.168.3.174:8080

User-Agent    Mozilla/5.0 (Windows NT 5.1; rv:5.0) Gecko/20100101 Firefox/5.0

Accept    text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8

Accept-Language    zh-cn,zh;q=0.5

Accept-Encoding    gzip, deflate

Accept-Charset    GB2312,utf-8;q=0.7,*;q=0.7

Connection    keep-alive

If-Modified-Since    Mon, 04 Jul 2011 10:12:40 GMT
多了一行If-Modified-Since,后台Nginx服务器的access.log也找到了该请求的记录,说明浏览器对这种情况的处理方法是:再问一下服务器,请求的URI在某个时间之后有没有被修改过,而这个时间是由上次HTTP响应的Last-Modified决定的。服务器鉴定之后,没有修改的话,返回304 Not Modified,浏览器收到后,从缓存里读出内容;有修改的话,返回200 OK,并返回新的内容。这种情况,就像你找到一盒已经过期的牛奶,于是问别人,还能不能喝,如果别人说可以,你就把它喝了,如果别人说不行,那你得就另外找一盒新鲜的牛奶。

至于F5刷新,其HTTP请求消息头如下:

Host    192.168.3.174:8080

User-Agent    Mozilla/5.0 (Windows NT 5.1; rv:5.0) Gecko/20100101 Firefox/5.0

Accept    text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8

Accept-Language    zh-cn,zh;q=0.5

Accept-Encoding    gzip, deflate

Accept-Charset    GB2312,utf-8;q=0.7,*;q=0.7

Connection    keep-alive

If-Modified-Since    Mon, 04 Jul 2011 10:12:40 GMT

Cache-Control    max-age=0

又多了一行Cache-Control: max-age=0,意思是说,我不管浏览器缓存中的文件过期没有,都去服务器询问一下,相当于上次HTTP响应的Expires暂时失效。服务器的响应处理流程同上。这种情况,就像你找到一盒牛奶,没有看它的有效期,直接就问别人能不能喝。

最后是Ctrl+F5刷新,其HTTP请求消息头如下:

Host    192.168.3.174:8080

User-Agent    Mozilla/5.0 (Windows NT 5.1; rv:5.0) Gecko/20100101 Firefox/5.0

Accept    text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8

Accept-Language    zh-cn,zh;q=0.5

Accept-Encoding    gzip, deflate

Accept-Charset    GB2312,utf-8;q=0.7,*;q=0.7

Connection    keep-alive

Pragma    no-cache

Cache-Control    no-cache

If-Modified-Since没有了,Cache-Control换成了no-cache,此外Pragma行是为了兼容HTTP1.0,作用与Cache-Control: no-cache是一样的。意思是,我不要缓存中的文件了,强制刷新,直接到服务器上重新下载,于是服务器的响应处理与首次请求这个URI一样,返回200 OK和新的内容。这种刷新,使用的网络流量是最大的,也是最耗时的。这就像你虽然发现了一盒牛奶,但是把它扔掉了,直接去买一盒新的。

  ps:来源:http://blog.csdn.net/yui/article/details/6584401

posted @ 2014-03-24 22:37  饮露秋林  阅读(351)  评论(0编辑  收藏  举报