我在此截屏视频中发现 ¹,您可以在 Ruby in Rails 中做一个更好的客户端缓存 ²考虑 REST + 填充 eTag 的模型。比渲染所有的 http 正文更聪明,只有在这一切之后,像往常一样计算 eTag。
这个属性可以让客户端在使用 GET 时缓存更加面向模型,所以我认为这对性能很有好处。
我没有看到有人用 asp.net MVC 做这个。会像我在 Rails 中看到这个人那样简单吗?
我在此截屏视频中发现 ¹,您可以在 Ruby in Rails 中做一个更好的客户端缓存 ²考虑 REST + 填充 eTag 的模型。比渲染所有的 http 正文更聪明,只有在这一切之后,像往常一样计算 eTag。
这个属性可以让客户端在使用 GET 时缓存更加面向模型,所以我认为这对性能很有好处。
我没有看到有人用 asp.net MVC 做这个。会像我在 Rails 中看到这个人那样简单吗?
eTag 是一个 HTTP 概念,而不是与任何一种服务器端技术相关。我相信与 IIS/MVC 相比,RoR 可以更容易地指示使用 eTag 缓存特定文件。
对于 IIS/MVC,您有两种设置响应标头的选项(可以包括 eTag 设置):
如果还有其他我没有列出的实现这一点的方法,我很想知道它们。
使用 ActionFilterAttribute 通过过滤器更新响应
public class ETagAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
filterContext.HttpContext.Response.Filter = new ETagFilter(filterContext.HttpContext.Response, filterContext.RequestContext.HttpContext.Request);
}
}
public class ETagFilter : MemoryStream
{
private HttpResponseBase _response = null;
private HttpRequestBase _request;
private Stream _filter = null;
public ETagFilter(HttpResponseBase response, HttpRequestBase request)
{
_response = response;
_request = request;
_filter = response.Filter;
}
private string GetToken(Stream stream)
{
byte[] checksum = new byte[0];
checksum = MD5.Create().ComputeHash(stream);
return Convert.ToBase64String(checksum, 0, checksum.Length);
}
public override void Write(byte[] buffer, int offset, int count)
{
byte[] data = new byte[count];
Buffer.BlockCopy(buffer, offset, data, 0, count);
var token = GetToken(new MemoryStream(data));
string clientToken = _request.Headers["If-None-Match"];
if (token != clientToken)
{
_response.Headers["ETag"] = token;
_filter.Write(data, 0, count);
}
else
{
_response.SuppressContent = true;
_response.StatusCode = 304;
_response.StatusDescription = "Not Modified";
_response.Headers["Content-Length"] = "0";
}
}
}