表单提交后,在输入中显示新值而不是缓存值

Posted

技术标签:

【中文标题】表单提交后,在输入中显示新值而不是缓存值【英文标题】:After form submit, show new values inside inputs instead of cached ones 【发布时间】:2013-06-25 08:18:21 【问题描述】:

注意:这不是缓存问题,也不是服务器配置错误,也不是浏览器问题。经过仔细调查,我发现问题是由于我的代码中的问题造成的: 很愚蠢,填充字段的选择查询在我的更新查询之前,导致表单始终显示更新之前的值。重新加载后,当然会出现新更新的值,导致我看错了方向。

然而,这个问题很好地概述了面临缓存问题时所有可能的解决方案。


我正在构建一个应用程序,其中包含由数据库中的值填充的表单。 用户可以更改表单的输入值。提交后(不是通过 AJAX),新值被保存到数据库并再次显示相同的表单,这次包含新值,直接从数据库加载。但是:我的浏览器(Windows 7 上的 Chrome v27.0.1453.116m)缓存了旧值。仅当我再次导航到我的页面时才会显示新值。

<form id="edit_form" class="form" action="http://the.same.url/" method="post">
  <input type="text" name="example" value="<?php echo $value_from_database; ?>" />
</form>  

我遇到了几种解决方案,但都没有完全解决问题:

在表单标签上设置属性autocomplete="off":这似乎没有效果。 在单个输入标签上设置属性autocomplete="off":即使与上述解决方案结合使用,这也不会产生结果 在页面加载时使用 javascript 重置表单:这会产生一些结果,但显然不会影响单选按钮和其他按钮。 防止通过元标记缓存页面,如下所示:Using <meta> tags to turn off caching in all browsers? 此外,通过 .htaccess 或 php 标头防止缓存无效。 按照 Miro Markarian 以下评论的建议,尝试通过向操作 URL 添加随机数来破坏缓存

以下是建议解决方案的概述:Make page to tell browser not to cache/preserve input values

我有哪些选择?如果可能的话,我想避免异步发布我的表单。它开始看起来好像我别无选择。任何意见表示赞赏。

请注意,此行为也会出现在其他浏览器中,例如 IE10。

我的页面标题与表单中一个输入的值相同,并且在提交新值时也不会更改,恕我直言,我们可以确定这是一个缓存问题。

Google Chromes 的 Web Developer 插件显示以下标题:

Pragma: no-cache
Date: Sun, 30 Jun 2013 09:44:12 GMT
Content-Encoding: gzip
Vary: Accept-Encoding
Server: Apache
Transfer-Encoding: chunked
Content-Type: text/html; charset=utf-8
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Connection: Keep-Alive
Keep-Alive: timeout=15, max=100
Expires: Thu, 19 Nov 1981 08:52:00 GMT

200 OK

【问题讨论】:

一种可能的解决方案是返回 url,并在 url 的末尾附加一个随机值......就像 ?nocache=875138 可以通过 php 中的 rand() 函数实现..跨度> 谢谢,我会马上调查的。 您确定是浏览器而不是服务器在缓存页面吗?您的应用程序是否发送 not-modified 标头? 这很奇怪。我的观点是,如果一个表单位于example.com/myform.php 并且您提交给example.com/myform.php?rnd=23215234,那么应该没有浏览器缓存该页面。我认为你在某处有一个错误配置的服务器。 将以下代码添加到您的 php 文件中:&lt;!-- This page was generated on &lt;?= date( 'D, d M Y H:i:s' ) ?&gt; --&gt; 并在提交前后检查页面。如果这条注释发生了变化,那么它就是 -no- 缓存问题,而是你的代码本身的问题。 【参考方案1】:

您可以通过一些随机字符串更改输入的名称属性并将它们存储在隐藏的输入中。

<form id="edit_form" class="form" action="http://the.same.url/" method="post">
  <input type="text" name="saejfb27982" value="..." />
  <input type="text" name="iuqde37we83" value="..." />
  <input type="hidden" name="associativeArray" value='"example":"saejfb27982","example2":"iuqde37we83"'>
</form>  

(由于每次名称都不一样,浏览器将无法匹配任何形式的缓存、自动补全……)

【讨论】:

+1 我正要写同样的。像这样的解决方案应该是恕我直言的方法 非常好的建议,谢谢。问题是表单相当复杂,有各种不同类型的输入和所见即所得......目前我认为几乎不可能对所有输入都做到这一点。【参考方案2】:

我感觉您的服务器发送304: Not Modified 而不是您通常发送的数据。如果您使用的是 apache,This question 可能会对您有所帮助。

我认为应该这样做(但未经测试)。它应该删除每个请求 php 文件的请求的 If-Modified-Since 标头,强制应用程序发送内容而不是 Not-Modified 状态。

<ifModule mod_headers.c>
<FilesMatch \.php$>
RequestHeader unset If-Modified-Since
</FilesMatch>
</ifModule>

【讨论】:

@maartenmachiels 200 OK 表示服务器向浏览器发送数据。它发送所有可能的标头以防止缓存,使发送的数据在过去某处过期,从而为浏览器提供额外的理由来使缓存无效(如果已缓存)。浏览器中的错误使其无论如何都使用缓存,浏览器扩展程序混乱或服务器发送了错误的数据。服务器可能有某种缓存,但如果不存在If-Modified-Since 标头,它会发送任何缓存似乎很奇怪。我有兴趣查看相关的 php 代码。 重建场景放到这里后,终于找到问题所在了。这是代码执行顺序的一个小例子......我的 SELECT(用于填充表单字段)在我的 UPDATE 之前,导致表单始终显示旧值。重新加载页面后,当然会显示正确的值:让我相信这是一个缓存问题!感谢您为我指明正确的方向!【参考方案3】:

你不能接受吗:

<form id="edit_form" class="form" action="http://the.same.url/" method="post">
 <input type="text" name="example" value="<?php echo $value_from_database; ?>" />
</form> 

并将其更改为:

value="<?php echo if(isset($_POST['example'])):$_POST['example']?$value_from_database; ?>

其中说:提交表单后,查看$_POST 数组中是否已有变量。如果我这样做,请使用该值,如果不是,请从 db 中提取。

您可能需要设置会话变量 ($_SESSION['ex'] = $_POST['example']),并对上面的代码进行调整

【讨论】:

您好,感谢您的回答。您能否详细说明您对“$_SESSION['ex']”的评论? 有时$_POST 数组会被弄乱,因此获取 POST 数据并将其放入 SESSION 变量会对其进行一些屏蔽。 我的页面标题,也是从数据库(用户名)中提取的,在更改相应输入中的值时也不会改变。因此我倾向于认为这是一个缓存问题。 提交通过 Jquery .submit() 提交后,加载相同的页面。我的应用程序的所有页面都位于 index.php 中。通过 .htaccess 进行 URL 重写。 这完全改变了问题。看起来它是一个 jQuery 而不是 PHP。您没有通过 JS 正确传递值【参考方案4】:

我相信您只是忘记了回显$value_from_database,这反过来又默认返回浏览器的缓存值。您应该使用以下输入元素:

<input type="text" name="example" value="<?php echo $value_from_database; ?>">

虽然这应该得到正确的 $value_from_database,但我不完全确定您为什么仍然无法完全关闭缓存。

【讨论】:

对不起,这是我的伪代码中的一个错误。这也让我感到困惑,为什么我的页面缓存仍然被加载。我一直在我的 .htaccess 文件中寻找冲突,但没有找到任何冲突。确实很奇怪。希望答案会出现。【参考方案5】:

this 问题的第一个答案建议添加以下标头以禁用浏览器缓存:

<?php
header("Expires: Tue, 01 Jan 2000 00:00:00 GMT");
header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
header("Cache-Control: no-store, no-cache, must-revalidate, max-age=0");
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache");
?>

【讨论】:

奇怪的是,这也解决不了问题。同时,我仅使用元标记尝试了您的解决方案...还有其他想法吗? 请注意,我可以从响应标头中清楚地看到这些设置处于活动状态。

以上是关于表单提交后,在输入中显示新值而不是缓存值的主要内容,如果未能解决你的问题,请参考以下文章

表单提交后如何在输入字段上显示表单提交值

表单提交后,我需要显示一条包含变量(来自表单的答案)的消息

html中提交表单后如何在同一页面上显示表格?

Laravel 重新提交表单验证仍然显示旧输入值

html提交表单后返回原页面并显示表单数据

提交表单后,子表单值在接收端显示为 null