我的ASP.NET MVC应用程序中有一个自定义的httpHandler,只要请求图像就会执行。如果我有这样的css定义:
div#cssSwitch
{
background-image: url('/Content/themes/base/images/a.png');
}
在页面加载期间执行处理程序。但是,我也有这块css
div#cssSwitch:hover
{
background-image: url('/Content/themes/base/images/b.png');
}
但永远不会为此图像执行处理程序。不是在页面加载期间,不是在元素上方悬停之后。为什么呢?
修改
到目前为止,我的处理程序是空的。我正在使用断点在本地调试它,以便在执行处理程序时应用程序中断。
到目前为止,:hover
上的图像似乎已被缓存。删除缓存时,它按预期工作。但是,我更喜欢一种拒绝缓存图像的方法。有东西吗?
问候,修剪。
答案 0 :(得分:3)
因为悬停事件是客户端的。一旦在第一次请求时加载图像,浏览器可能会缓存它。因此,您的处理程序不会在后续请求中执行。
答案 1 :(得分:1)
浏览器使用“普通”GET,并且应该注意HTTP标头,就像对任何其他图像提取一样。
要防止缓存,请发送回适当的HTTP处理程序(“no-cache”等)。也可以发回“304 Not Modified”以避免在可能的情况下发送数据,同时仍让客户端“重新请求”图像。
然而,图像请求只会发生一次,除非CSS属性已更改 (例如在JavaScript中) - 即使缓存是禁用。此外, CSS在应用样式时不会“执行”;资源只是它们的本质。这意味着浏览器可以 - 并且可能 - 在之前加载CSS 中的所有url()
资源。应用。实际的装载顺序/时间是未指定的AFAIK,但是急切加载更加容易且更加一致。
如上所述,使用JS中的动态属性集可能会让浏览器按照GET规则重新获取资源,但此时尝试使用CSS完全没有问题。< / p>
快乐的编码。
答案 2 :(得分:0)
CSS表达式如:Hover,期望找到它指向的文件,不需要额外的工作。
在您提到的情况下,假设您的处理程序可以处理对Images的请求,您可以将此文件作为完整URL提供,因此,处理程序将带头并提供文件。
所以代替:
div#cssSwitch:hover
{
background-image: url('/Content/themes/base/images/b.png');
}
它应该是:
div#cssSwitch:hover
{
background-image: url('http://www.MY_WEB_SITE.com/Content/themes/base/images/b.png');
}
答案 3 :(得分:0)
这很可能是因为您的浏览器在第一页加载时缓存了图像,因此在您下次查看或刷新页面时从本地缓存中检索图像。
你可以尝试硬刷新,通常按住ctrl键并按F5。
如果您想永久停止缓存,可以使用
Response.Cache.SetExpires(DateTime.UtcNow.AddDays(-1));
Response.Cache.SetValidUntilExpires(false);
Response.Cache.SetRevalidation(HttpCacheRevalidation.AllCaches);
Response.Cache.SetCacheability(HttpCacheability.NoCache);
Response.Cache.SetNoStore();
有关如何创建自定义属性的详细信息,请查看this answer或this answer。
答案 4 :(得分:0)
如果您没有使用控制器来提供图像,则必须在IIS中设置缓存。
如果您使用控制器来提供图像,您可以使用此属性修饰动作/控制器
[Cache(Duration=0)]
public ActionResult Image(string imageName)
{
// return the image
}
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
public class CacheAttribute : ActionFilterAttribute
{
public CacheAttribute()
{
Duration = 10;
}
/// <summary>
/// Gets or sets the cache duration in seconds. The default is 10 seconds.
/// </summary>
/// <value>The cache duration in seconds.</value>
public int Duration
{
get;
set;
}
public override void OnActionExecuted(ActionExecutedContext filterContext)
{
if (Duration <= 0) return;
HttpCachePolicyBase cache = filterContext.HttpContext.Response.Cache;
TimeSpan cacheDuration = TimeSpan.FromSeconds(Duration);
cache.SetCacheability(HttpCacheability.Public);
cache.SetExpires(DateTime.Now.Add(cacheDuration));
cache.SetMaxAge(cacheDuration);
cache.AppendCacheExtension("must-revalidate, proxy-revalidate");
}
}