先看 MSDN 对该方法的说明:
----以下摘自MSDN文档---(再次怀疑MSDN中文版的翻译人员是在国外读的中文!不得已将中英文同时列出来,否则可能看不懂。)----------
当 allow 参数为 true 时,将使响应在客户端浏览器“历史记录”缓存中可用,而不论服务器上所做的 HttpCacheability 设置是什么。
Makes the response is available in the client browser History cache, regardless of the HttpCacheability setting made on the server, when the allow parameter is true.
public void SetAllowResponseInBrowserHistory(bool allow)
参数
allow
true 指示客户端浏览器将响应存储在“历史记录”文件夹中,否则为 false。默认为 false。
true to direct the client browser to store responses in the History folder; otherwise false. The default is false.
当 HttpCacheability 设置为 NoCache 或 ServerAndNoCache 时,Expires HTTP 标头默认设置为 -1,这样就会告知客户端不要将响应缓存在“历史记录”文件夹中,这样,使用后退/前进按钮时,客户端每次都请求一个新的响应版本。通过在将 allow 参数设置为 true 的情况下调用 SetAllowResponseInBrowserHistory 方法,您可以重写此行为。
When HttpCacheability is set to NoCache or ServerAndNoCache the Expires HTTP header is by default set to -1; this tells the client not to cache responses in the History folder, so that when you use the back/forward buttons the client requests a new version of the response each time. You can override this behavior by calling the SetAllowResponseInBrowserHistory method with the allow parameter set to true.
如果将 HttpCacheability 设置为除 NoCache 或 ServerAndNoCache 以外的值,则使用 allow 的任一个值调用 SetAllowResponseInBrowserHistory 方法都将无效。
If HttpCacheability is set to values other than NoCache or ServerAndNoCache, calling the SetAllowResponseInBrowserHistory method with either value for allow has no effect.
----End-------------
费 了半天劲,大概看明白了 SetAllowResponseInBrowserHistory 的用途。当使用 SetCacheability(NoCache) 或 SetCacheability(ServerAndNoCache) 时,浏览器不会将网页输出结果缓存到客户端历史文件夹中。而 SetAllowResponseInBrowserHistory(true) 的作用让浏览器不要管 Control-Cache 设置,依然将输出结果缓存到历史文件夹中。
事实果真如此吗?先看看使用了 SetAllowResponseInBrowserHistory(true) 的 Http Headers 有什么不同。
protected void Page_Load(object sender, EventArgs e)
{
this.Response.Write(DateTime.Now.ToString());
this.Response.Cache.SetCacheability(HttpCacheability.NoCache);
//this.Response.Cache.SetAllowResponseInBrowserHistory(true);
}
{
this.Response.Write(DateTime.Now.ToString());
this.Response.Cache.SetCacheability(HttpCacheability.NoCache);
//this.Response.Cache.SetAllowResponseInBrowserHistory(true);
}
添加前
HTTP/1.1 200 OK
Server: Microsoft-IIS/5.1
Date: Wed, 30 Aug 2006 13:12:47 GMT
X-Powered-By: ASP.NET
X-AspNet-Version: 2.0.50727
Cache-Control: no-cache
Pragma: no-cache
Expires: -1
Content-Type: text/html; charset=utf-8
Content-Length: 883
Server: Microsoft-IIS/5.1
Date: Wed, 30 Aug 2006 13:12:47 GMT
X-Powered-By: ASP.NET
X-AspNet-Version: 2.0.50727
Cache-Control: no-cache
Pragma: no-cache
Expires: -1
Content-Type: text/html; charset=utf-8
Content-Length: 883
添加后
HTTP/1.1 200 OK
Server: Microsoft-IIS/5.1
Date: Wed, 30 Aug 2006 13:13:21 GMT
X-Powered-By: ASP.NET
X-AspNet-Version: 2.0.50727
Cache-Control: no-cache
Pragma: no-cache
Content-Type: text/html; charset=utf-8
Content-Length: 883
Server: Microsoft-IIS/5.1
Date: Wed, 30 Aug 2006 13:13:21 GMT
X-Powered-By: ASP.NET
X-AspNet-Version: 2.0.50727
Cache-Control: no-cache
Pragma: no-cache
Content-Type: text/html; charset=utf-8
Content-Length: 883
两者的差别就是少了 "Expires: -1"。
没办法,我们使用 Reflector 看看反编译的代码。
public void SetAllowResponseInBrowserHistory(bool allow)
{
if ((this._allowInHistory == -1) || (this._allowInHistory == 1))
{
this.Dirtied();
this._allowInHistory = allow ? 1 : 0;
}
}
private void Dirtied()
{
this._isModified = true;
this._useCachedHeaders = false;
}
private void UpdateCachedHeaders(HttpResponse response)
{
if (!this._useCachedHeaders)
{
// ... 省略部分代码 ...
switch (cacheability1)
{
case HttpCacheability.NoCache:
case HttpCacheability.Server:
// ... 省略部分代码 ...
if (this._allowInHistory != 1)
{
if (HttpCachePolicy.s_headerExpiresMinus1 == null)
{
HttpCachePolicy.s_headerExpiresMinus1 = new HttpResponseHeader(0x12, "-1");
}
this._headerExpires = HttpCachePolicy.s_headerExpiresMinus1;
}
break;
// ... 省略部分代码 ...
}
this._useCachedHeaders = true;
}
}
{
if ((this._allowInHistory == -1) || (this._allowInHistory == 1))
{
this.Dirtied();
this._allowInHistory = allow ? 1 : 0;
}
}
private void Dirtied()
{
this._isModified = true;
this._useCachedHeaders = false;
}
private void UpdateCachedHeaders(HttpResponse response)
{
if (!this._useCachedHeaders)
{
// ... 省略部分代码 ...
switch (cacheability1)
{
case HttpCacheability.NoCache:
case HttpCacheability.Server:
// ... 省略部分代码 ...
if (this._allowInHistory != 1)
{
if (HttpCachePolicy.s_headerExpiresMinus1 == null)
{
HttpCachePolicy.s_headerExpiresMinus1 = new HttpResponseHeader(0x12, "-1");
}
this._headerExpires = HttpCachePolicy.s_headerExpiresMinus1;
}
break;
// ... 省略部分代码 ...
}
this._useCachedHeaders = true;
}
}
从上面的代码来看,基本上就是设置 "Expires: -1" 这么个 Http Header,这也符合两次 HttpHeaders 捕获结果的差异。
到 这一步,只好做实际操作试验了。如何试验 SetAllowResponseInBrowserHistory(true) 的作用呢?我们知道使用了 NoCache 后,按浏览器后退按钮返回时应该显示 "网页已经过期",那么我们就用这个测试一下。新建一个空白网页(WebPage),然后在页面放置一个按钮 Button1(服务端控件) 来触发 PostBack(Submit)。
测试1
protected void Page_Load(object sender, EventArgs e)
{
this.Response.Write(DateTime.Now.ToString());
this.Response.Cache.SetCacheability(HttpCacheability.NoCache);
}
{
this.Response.Write(DateTime.Now.ToString());
this.Response.Cache.SetCacheability(HttpCacheability.NoCache);
}
单击 Button1 后,浏览器后退按钮可用。单击后退按钮返回上一页,未出现 "网页已经过期"。
单击 Button1 两次或两次以上,返回时出现 "警告: 网页已经过期"。
(晕~~~~ 为什么会是这样?非得多按几次?)
测试2
protected void Page_Load(object sender, EventArgs e)
{
this.Response.Write(DateTime.Now.ToString());
this.Response.Cache.SetCacheability(HttpCacheability.NoCache);
this.Response.Cache.SetAllowResponseInBrowserHistory(true);
}
{
this.Response.Write(DateTime.Now.ToString());
this.Response.Cache.SetCacheability(HttpCacheability.NoCache);
this.Response.Cache.SetAllowResponseInBrowserHistory(true);
}
单击 Button1 后,浏览器后退按钮可用。单击后退按钮返回上一页,未出现 "网页已经过期"。
单击 Button1 两次或两次以上,返回时出现 "警告: 网页已经过期"。
得!这回傻大发了~~~~~ 试验结果就是:根本没什么用处吗!
由于客户端缓存是由浏览器控制,而网页输出结果的差异又仅仅是 "Expires: -1",因此问题应该出在 IE 浏览器身上。在网上找了找,对此有疑问的似乎不多,幸好翻出几个同道中人。可惜《Cache feature doesn't produce expected result (bug?) 》这篇帖子里,两位老兄讨论到最后也没个结果。
头痛!提几点结论。
1. 希望微软(中国)以后在招聘要求上除注明英语几级外,还得加上"中文表达能力流畅"。这年头中文没英文好的 "中国人" 大有人在。
2. 这算不算是个Bug?如果是雨痕理解错误,欢迎哪位解惑答疑一番。
3. 既然没有作用(假定我的推论正确),那么多人还是照搬照用,是缺乏深入研究的精神?还是人云亦云,根本不懂?
4. 微软有可能再次发扬了其不遵守标准的伟大精神。(RFC 2616 - Hypertext Transfer Protocol -- HTTP/1.1,section 13.13,"a cache-control:no-cache does mean a request to the server if you hit back")
希望有兄弟给解答一下!郁闷中……