题
我有一个网页 x.php
(在密码保护的网站),它有一个形式和一个按钮,它使用的 POST
方法发送的形式的数据和打开了 x.php#abc
.这一工作得很好。
但是,如果用户决定返回在Internet Explorer7,所有的领域中原始的 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");
和它们的变化。没有成功。看回头这样的工具 查看 表示我认为Apache是事实上履行我的头。
所以我的问题是:我做错了什么?
解决方案
即 将 保留的形式内容背的按一下按钮自动的,只要:
- 你还没有破碎的cacheing与no-cache pragma或类似的
- 形式领域中的问题不是动态创建的脚本
你似乎有cacheing在手,所以我猜是后者可能适用。(作为mkoeller说,火狐避免了这个问题如果页面是在过去几回击通过保持页面本身的活时间超过它在屏幕上。然而,这是任选的,并且Firefox将恢复为相同的行为即和其他浏览器一旦你浏览了一些网页之前,它已经过期。)
如果你创造你自己的形式领域从脚本加载,然后浏览器也没有办法知道新的输入控制是'相同的'老实例,因此它不能填满它在与先前提交的价值。在这种情况下,如果你想要它玩好与返回按钮你必须开始存储数据的客户。
然后你必须使用某种国键因此,每一组数据是依赖于一个实例的网页,否则通过多个实例同样的形式或具有两个浏览器标签上打开的形式,在一次将严重混淆你的脚本。
和 然后 你开始收集了很多数据,如果他们是很大的形式,而如果客户端存储机构您使用的是饼干,您可以开始失去的数据,以及发送载的不必要状态的废话与每HTTP请求。其他客户端存储机制可用,但他们的浏览器特有的。
在短:做动态所产生的形式是很好的一个巨大的痛苦和也许最好避免的,如果你可以的。具有一个隐藏的形式在网页上的那个脚本使得可见的,因此允许浏览器来做自己的领域-记住的-魔术而不是给你的任务,通常容易得多。
其他提示
在尝试进一步缩小问题的范围时,我找到了问题的原因。我正在使用被Apache重写的URL(即我总是以 http://foo.com/page
的形式访问我的页面,这是由Apache映射到 http://foo.com /page.htm 代码>)。使用真正的 URL解决了问题并使IE7满意,只要我指定正确的HTTP头(
Cache-Control
, Expires
等等) )。
以下是我在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(在尝试进一步缩小问题的范围时,我找到了问题的原因。我正在使用被Apache重写的URL(即我总是以 http://foo.com/page
的形式访问我的页面,这是由Apache映射到 http://foo.com /page.htm 代码>)。使用真正的 URL解决了问题并使IE7满意,只要我指定正确的HTTP头( Cache-Control
, Expires
等等) )。
以下是我在PHP代码中输出的标题,这些标题似乎使所有浏览器都对缓存感到满意:
<*>SERVER['HTTP_IF_MODIFIED_SINCE'])
? stripslashes(在尝试进一步缩小问题的范围时,我找到了问题的原因。我正在使用被Apache重写的URL(即我总是以 http://foo.com/page
的形式访问我的页面,这是由Apache映射到 http://foo.com /page.htm 代码>)。使用真正的 URL解决了问题并使IE7满意,只要我指定正确的HTTP头( Cache-Control
, Expires
等等) )。
以下是我在PHP代码中输出的标题,这些标题似乎使所有浏览器都对缓存感到满意:
<*>SERVER['HTTP_IF_MODIFIED_SINCE']) : false;
$if_none_match = isset(在尝试进一步缩小问题的范围时,我找到了问题的原因。我正在使用被Apache重写的URL(即我总是以 http://foo.com/page
的形式访问我的页面,这是由Apache映射到 http://foo.com /page.htm 代码>)。使用真正的 URL解决了问题并使IE7满意,只要我指定正确的HTTP头( Cache-Control
, Expires
等等) )。
以下是我在PHP代码中输出的标题,这些标题似乎使所有浏览器都对缓存感到满意:
<*>SERVER['HTTP_IF_NONE_MATCH'])
? stripslashes(在尝试进一步缩小问题的范围时,我找到了问题的原因。我正在使用被Apache重写的URL(即我总是以 http://foo.com/page
的形式访问我的页面,这是由Apache映射到 http://foo.com /page.htm 代码>)。使用真正的 URL解决了问题并使IE7满意,只要我指定正确的HTTP头( Cache-Control
, Expires
等等) )。
以下是我在PHP代码中输出的标题,这些标题似乎使所有浏览器都对缓存感到满意:
<*>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"
Firefox做这种缓存。据我了解你的问题,你希望IE7的行为与Firefox一样。我认为这是不可能的。
Firefox和IE7在解释后退按钮的方式上有所不同。
Firefox将显示上一页的DOM树,因为它是在页面离开之前最后显示的。也就是说,所有表单数据仍将包含在表单的输入字段中。但是,在按下后退按钮时,您将看不到 onload
事件。
IE7将根据从服务器收到的响应再次呈现页面。因此表单是emtpy(除非服务器最初发送了默认值),但你会看到 onload
事件。
所以我设计了一个后退按钮缓存。
它的邪恶和糟糕的网络,但它使页面能够表现人们期望他们的行为,而不是在整个地方神奇地扭曲。
<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>
这会有一点神奇之处在于它会检测您当前/正在查看的页面是否是从缓存加载的。
如果你第一次在那里,它会检测到“没有哈希”。 ,并添加“ #_
”到页面网址。
如果您在第一次使用&gt;(即:不是指向该页面的直接链接),该页面上已经有#_,因此它将其删除,并在删除它的过程中触发页面重新加载。
您可以使用autocomplete =&quot; off&quot;在你的领域。 这样,浏览器不会缓存这些值,因此当用户单击后退按钮时,不会在表单中填充值。