Ste*_*unn 8 .net http wininet http-caching asp.net-web-api
我正在尝试在我的.NET客户端和服务器之间进行缓存.在WinInet决定缓存结果之前,我看到一个看似随机的端点命中数.
.NET客户端使用HttpWebRequest
以下命令发出请求
HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(uiTextBoxUrl.Text);
var policy = new RequestCachePolicy(RequestCacheLevel.CacheIfAvailable);
webRequest.CachePolicy = policy;
WebResponse webResponse = webRequest.GetResponse();
Run Code Online (Sandbox Code Playgroud)
使用ASP.net Web API实现的服务器设置以下CacheControl
标头:
response.Headers.CacheControl = new CacheControlHeaderValue
{
MaxAge =3600,
MustRevalidate = true,
Public = true,
Private = true
};
Run Code Online (Sandbox Code Playgroud)
使用带有将请求发送到端点的按钮的测试工具,我可以看到,即使CacheIfAvailable
使用了,也不会立即缓存响应.通过检查我的服务器上的调试输出,我发现在最终缓存请求之前需要触发看似随机数量的命中(或者更有可能是命中计数/经过时间启发式).如果我快速敲击测试按钮,它将在大约10次点击后开始缓存.如果我每隔1或2秒点击一次按钮,我就会计算最多25次点击,然后再进行缓存.
这是我从Fiddler看到的回应:
HTTP/200 responses are cacheable by default, unless Expires, Pragma, or Cache-Control headers are present and forbid caching.
HTTP/1.1 Cache-Control Header is present: public, must-revalidate, max-age=3600, private
private: This response MUST NOT be cached by a shared cache.
public: This response MAY be cached by any cache.
max-age: This resource will expire in 1 hours. [3600 sec]
must-revalidate: After expiration, the server MUST be contacted to verify the freshness of this resource.
HTTP/1.1 ETAG Header is present: "3488770a-8659-4fc0-b579-dcda9200a1c7"
Run Code Online (Sandbox Code Playgroud)
我已经读过HttpWebRequest
使用WinInet进行缓存,所以我很好奇WinInet如何确定什么时候需要缓存,更具体地说,为什么它不会在第一次打击时缓存?
我使用 RequestCacheLevel.Default,否则我发现 Wininet 会很乐意提供过时的响应。
我也不使用必须重新验证,因为我认为一旦缓存的响应过时,这是默认行为。
我相信,如果您始终在请求中包含 LastModifed 或 Etag,那么默认情况下您将获得本地副本,直到它过期(因为您设置了 Private 和 MaxAge),一旦过期,您可能会收到 304 返回,在这种情况下将使用本地副本。
话虽如此,请检查您对变化标头的响应。在许多情况下,Vary 标头将阻止 Wininet 的使用,因为它不正确支持 Vary 标头。
使用该控制器,
public class PrivateCachingController : ApiController
{
public HttpResponseMessage Get()
{
var response = new HttpResponseMessage()
{
Content = new StringContent("This is cached content")
};
response.Headers.CacheControl = new CacheControlHeaderValue() {MaxAge = new TimeSpan(0,0,0,60)};
return response;
}
}
Run Code Online (Sandbox Code Playgroud)
和这个客户端代码,
var clientHandler = new WebRequestHandler();
clientHandler.CachePolicy = new RequestCachePolicy(RequestCacheLevel.Default);
var client = new HttpClient(clientHandler) { BaseAddress = _BaseAddress };
var response = await client.GetAsync("/PrivateCaching");
var response2 = await client.GetAsync("/PrivateCaching");
Run Code Online (Sandbox Code Playgroud)
当它执行时,只有一个请求通过网络发出。
归档时间: |
|
查看次数: |
861 次 |
最近记录: |