浏览器后退按钮可恢复空字段

internet-explorer back-button

24260 观看

6回复

6578 作者的声誉

我有一个网页x.php(在我的网站的密码保护区域),它有一个表单和一个按钮,使用该POST方法发送表单数据并打开x.php#abc。这非常有效。

但是,如果用户决定在Internet Explorer 7中导航回来,则会x.php清除原始文件中的所有字段,并且必须再次输入所有字段。我无法在会话中保存发布的信息,我试图了解如何让IE7按照我想要的方式运行。

我在网上搜索并找到了答案,表明HTTP标头应该包含显式的缓存信息。目前,我试过这个:

session_name("FOO");
session_start();
header("Pragma: public");
header("Expires: Fri, 7 Nov 2008 23:00:00 GMT");
header("Cache-Control: public, max-age=3600, must-revalidate");
header("Last-Modified: Thu, 30 Oct 2008 17:00:00 GMT");

及其变化。没有成功。使用WireShark等工具查看返回的标题,可以看出Apache确实很尊重我的标题。

所以我的问题是:我做错了什么?

作者: Pierre Arnaud 的来源 发布者: 2008 年 11 月 4 日

回应 (6)


3

4123 作者的声誉

Firefox做这种缓存。据我了解你的问题,你希望IE7的行为与Firefox一样。我认为这是不可能的。

Firefox和IE7在解释后退按钮的方式上有所不同。

Firefox将显示上一页的DOM树,因为它是在页面离开之前最后显示的。也就是说,所有表单数据仍将包含在表单的输入字段中。但是onload在按下后退按钮时你不会看到一个事件。

IE7将根据从服务器收到的响应再次呈现页面。因此表单是emtpy(除非服务器最初发送了默认值),但您会看到一个onload事件。

作者: mkoeller 发布者: 04.11.2008 10:06

2

50841 作者的声誉

我戳了戳,这是一个非常难的问题。它也是动态修改内容的主要痛苦。你访问该页面,javascript用你的指令增加它,你转到下一页,然后回来,javascript已经忘记了。并且没有办法简单地更新页面服务器端,因为页面来自缓存。

所以我设计了一个后退按钮缓存。

它的邪恶和不利于网络,但它使页面能够表现人们期望他们的行为,而不是整个地方神奇地扭曲。

<script type="text/javascript">//<!-- <![CDATA[
(function(){
    if( document.location.hash === "" )
    {
        document.location.hash="_";
    }
    else
    {
      var l = document.location;
      var myurl = ( l.protocol + "//" + l.hostname + l.pathname + l.search); 
      document.location = myurl;
    }
})();
//]]> --></script>

这会有一点神奇之处在于它会检测您当前/正在查看的页面是否是从缓存加载的。

如果你第一次在那里,它将检测到“无哈希”,并#_在页面网址中添加“ ”。如果你在那里第一次(即:不是直接链接到页面),页面上已经有#_,所以它将其删除,并在删除它的过程中,触发页面重新加载。

作者: Kent Fredric 发布者: 04.11.2008 10:45

11

454773 作者的声誉

决定

IE 自动在后退按钮上保留表单内容,只要:

  • 你没有使用no-cache pragma或类似的方法破坏缓存
  • 有问题的表单字段不是由脚本动态创建的

你似乎手头有缓存,所以我猜测后者可能适用。(正如mkoeller所说,如果页面在最后几次后退点击中,通过保持页面本身的活动时间长于屏幕上的时间,Firefox可以避免此问题。但这是可选的,Firefox将恢复到与IE和其他相同的行为浏览器一旦你浏览了几页,它已经过期了。)

如果您是从脚本onload创建自己的表单字段,那么浏览器无法知道新输入控件与旧实例“相同”,因此无法使用先前提交的值填充它。在这种情况下,如果您希望它与后退按钮一起使用,您必须开始在客户端上存储数据。

然后你必须使用某种状态键,以便每组数据都与页面的一个实例绑定,否则通过同一表单的多个实例或在表单上打开两个浏览器选项卡将严重混淆你的脚本。

随后你开始收集大量的数据,如果他们是大单,如果你正在使用的客户端的存储机制是饼干,你可以开始丢失数据,以及发送不必要的状态废话的负载每个HTTP请求。其他客户端存储机制可用,但它们是特定于浏览器的。

简而言之:很好地完成动态生成的表单是一个巨大的痛苦,如果可以,最好避免。在页面上有一个隐藏的表单,脚本可以看到,从而允许浏览器进行字段记忆 - 魔术而不是给你任务,通常要容易得多。

作者: bobince 发布者: 04.11.2008 11:16

1

2882 作者的声誉

您可以在字段中使用autocomplete =“off”。这样,浏览器不会缓存这些值,因此当用户单击后退按钮时,不会在表单中填充这些值。

作者: Bogdan 发布者: 04.11.2008 12:12

4

6578 作者的声誉

在尝试进一步缩小问题的范围时,我发现了问题的原因。我正在使用由Apache重写的URL(即我总是访问我的页面,http://foo.com/page由Apache映射http://foo.com/page.htm)。使用真实的URL解决了这个问题并提出IE7快乐,只要我指定适当的HTTP标头(Cache-ControlExpires,等)。

以下是我在PHP代码中输出的标题,它们似乎使所有浏览器都对缓存感到满意:

function emitConditionalGet($timestamp)
{
    // See also http://www.mnot.net/cache_docs/
    // and code sample http://simonwillison.net/2003/Apr/23/conditionalGet/

    $gmdate_exp    = gmdate('D, d M Y H:i:s', time() + 1) . ' GMT';
    $last_modified = gmdate('D, d M Y H:i:s', $timestamp) . ' GMT';
    $etag          = '"'.md5($last_modified).'"';

    // If the client provided any of the if-modified-since or if-none-match
    // infos, take them into account:

    $if_modified_since = isset($_SERVER['HTTP_IF_MODIFIED_SINCE'])
                       ? stripslashes($_SERVER['HTTP_IF_MODIFIED_SINCE']) : false;
    $if_none_match     = isset($_SERVER['HTTP_IF_NONE_MATCH'])
                       ? stripslashes($_SERVER['HTTP_IF_NONE_MATCH'])     : false;

    if (!$if_modified_since && !$if_none_match)
    {
        return;  // the client does not cache anything
    }

    if ($if_none_match && $if_none_match != $etag)
    {
        return;  // ETag mismatch: the page changed!
    }
    if ($if_modified_since && $if_modified_since != $last_modified)
    {
        return;  // if-modified-since mismatch: the page changed!
    }

    // Nothing changed since last time client visited this page.

    header("HTTP/1.0 304 Not Modified");
    header("Last-Modified: $last_modified");
    header("ETag: $etag");
    header("Cache-Control: private, max-age=1, must-revalidate");
    header("Expires: $gmdate_exp");
    header("Pragma: private, cache");
    header("Content-Type: text/html; charset=utf-8");
    exit;
}

function emitDefaultHeaders($timestamp)
{
    $gmdate_exp    = gmdate('D, d M Y H:i:s', time() + 1) . ' GMT';
    $last_modified = gmdate('D, d M Y H:i:s', $timestamp) . ' GMT';
    $etag          = '"'.md5($last_modified).'"';

    header("Last-Modified: $last_modified");
    header("ETag: $etag");
    header("Cache-Control: private, max-age=1, must-revalidate");
    header("Expires: $gmdate_exp");
    header("Pragma: private, cache");
    header("Content-Type: text/html; charset=utf-8");
}

function getTimestamp()
{
    // Find out when this page's contents last changed; in a static system,
    // this would be the file time of the backing HTML/PHP page. Add your
    // own logic here:
    return filemtime($SCRIPT_FILENAME);
}

// ...

$timestamp = getTimestamp();
emitConditionalGet($timestamp);
emitDefaultHeaders($timestamp); //previously, this variable was mistyped as "$timestaml"
作者: Pierre Arnaud 发布者: 04.11.2008 02:30

0

25 作者的声誉

这是一个老帖子,自那以后发生了很多变化。尽管如此,我的一个表格(但Chrome表现不佳)我遇到了这个问题。如果回去,它会清除所有信息。我完全找到了解决方法并需要在这里分享,因为它太奇怪了。可能它不是发布这个的最好的地方,但我们走了。

这就是我所拥有的(一个精简的版本,而不是工作。)

<table>
    <form>
    <tr>
        <td><input type="number" value="0"></td>
    </tr>
    </form>
</table>

而这个固定(现在的工作。)移动<form>的外标签<table><tr>标签。

<form>
<table>
    <tr>
        <td><input type="number" value="0"></td>
    </tr>
</table>
</form>
作者: MeSo2 发布者: 10.07.2019 10:15
32x32