在css中请求时如何提供文件:将鼠标悬停为背景图像

时间:2011-03-26 19:44:12

标签: asp.net css asp.net-mvc asp.net-mvc-3 hover

我的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上的图像似乎已被缓存。删除缓存时,它按预期工作。但是,我更喜欢一种拒绝缓存图像的方法。有东西吗?

问候,修剪。

5 个答案:

答案 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 answerthis 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");
    }
}