我有一个页面,其中包含用于网站搜索的表单。表单使用POST动词提交要搜索的数据。搜索结果在提交后显示在表单下。
为了解决IE上的“Page has expired”问题,我使用了所谓的PRG模式(http://en.wikipedia.org/wiki/Post/Redirect/Get)。所以我从我的view的post()方法返回django.shortcuts.redirect(),该方法重定向到同一个URL。
问题是在生产中我看到与302响应之后发送的GET请求相关联的不同会话ID。因为我将表单存储在会话中以便能够将结果拆分为页面,所以我得到了不一致的结果。
我在apache / mod_wsgi下运行django。 apache配置为最多运行3个进程。
在重新启动httpd后不会发生这种情况,似乎在httpd进程占用的内存量达到某个限制后,它就会开始发生。
我通过反复按提交按钮来检查这个,表单从会话中填充,这样我就可以看到我输入的搜索字符串了。会话更改时,表单返回空白。因此,当这种情况开始发生时,表单连续成功填充2次,当我第三次按提交时,它返回空白,这意味着服务器返回了新的会话cookie。这似乎与ServerLimit设置有关。
有什么问题?有什么想法吗?
感谢
康斯坦丁
答案 0 :(得分:1)
您是否尝试过使用HTTP 303请参阅其他响应而不是302?
http://tumblr.jonthornton.com/post/7902581999/preventing-form-re-submission-with-http-303-redirects
答案 1 :(得分:1)
你正在使用Django Sessions App正确吗?
如果是这种情况,则将当前会话ID存储在cookie中,该cookie的名称使用设置SESSION_COOKIE_NAME
指定,并且默认为sessionid。由于您在Firefox中没有遇到此问题,我认为应该可以安全地假设您在Django中的会话处理和存储工作正常。
这里最可能的罪魁祸首是IE正在丢失/删除sessionid cookie,导致它在重定向后开始新的会话。关于这个主题的快速谷歌似乎证实了这一点。
您可以在以下网址查看相关信息:
现在,为了真正解决您的问题。除非实际需要,否则Django不会设置会话cookie(例如,如果您设置会话数据)。如果POST时设置会话数据的唯一位置在视图中,那么IE将丢弃设置sessionid的cookie。
所以一个快速而简单的bandaid只是在GET期间将一些垃圾数据(或默认值?)保存到会话中以显示POST之前的表单,即IE将获取sessionid cookie,事情应该是工作
答案 2 :(得分:0)
IE获得302重定向时会打开一个新连接。这就是为什么302解决了你的页面已经过期的问题。但这也意味着你正在为一个新的“会话”服务。
除了依赖于连接之外,您还需要一些其他机制来跟踪302中的会话。