在Post / Redirect / Get上重新加载WebKit图像

时间:2010-11-29 06:37:41

标签: post redirect webkit get

我们刚刚重新设计了一个网络应用程序,因此我们注意到Chrome中存在一个错误(但据说会影响所有WebKit浏览器),导致在Post / Redirect / Get之后重新加载完整的image / js / css。我们的应用程序是使用ASP.NET构建的,并使用了大量的Response.Redirect,这意味着用户将会遇到很多问题。针对测试用例的问题有一个错误报告:https://bugs.webkit.org/show_bug.cgi?id=38690

我们已尝试以下方法解决此问题:

  • 将所有Response.Redirects更改为JavaScript重定向。这并不理想,因为在重新加载图像时,页面过渡期间会出现“白色闪烁”。
  • 我们为图像,CSS和JS文件编写了自己的HTTP处理程序。我们将其设置为处理程序发送最长1小时的位置。当客户端再次请求该文件时,处理程序检查浏览器发送的If-Modified-Since标头,以查看该文件自上次下载以来是否已更新。如果日期匹配,则处理程序返回HTTP 302(未修改),其中Content-Length为0。我们进行了测试,如果第一次下载图像(HTTP 200),则会有10秒的延迟。所以第一次加载页面时,速度非常慢。如果处理程序返回302(未修改),则没有延迟。我们注意到,即使服务器返回302(未修改),Chrome仍会“重新加载”图像。它不是从服务器中提取文件(如果是,它会导致10秒的延迟),但它会闪烁/重新加载图像。所以Chrome似乎忽略了302并仍然从它的缓存重新加载图像导致“重新加载”。

我们检查了大型网站,看看他们是否已经以某种方式修复了它,但NewEgg和亚马逊等网站也受到了影响。

有没有人找到解决方案?或者最小化影响的方法?

感谢。

2 个答案:

答案 0 :(得分:1)

这是一个错误。我见过的唯一“解决方法”现在是使用Refresh标头而不是Location标头来进行重定向。这远非理想。

Bug 38690 - Submitting a POST that leads to a server redirect causes all cached items to redownload

此外,此问题与“Full page reload on Post/Redirect/Get ignoring cache control”重复。

答案 1 :(得分:0)

我自己使用的ASP.NET Web表单站点遇到了这个问题 在其许多页面上发布帖子之后的Response.Redirect(url,false)。

从阅读HTTP / 1.1规范来看,听起来像303响应代码对于实现Request:POST,Response:Redirect行为是正确的。不幸的是,更改状态代码并不能使浏览器缓存在Chrome中正常运行。

我通过为非静态内容创建自定义模块来实现上述帖子中描述的变通方法。我还要删除302的响应内容,以避免出现“对象移动到此处”的眨眼。这可能仅与刷新标头相关。欢迎提出意见!

public class WebKitHTTPHeaderFixModule : IHttpModule 
{ 
    public void Init(HttpApplication httpApp) 
    { 
        // Attach application event handlers. 
        httpApp.PreSendRequestHeaders += new EventHandler(httpApp_PreSendRequestHeaders);
    }

    void httpApp_PreSendRequestHeaders(object sender, EventArgs e)
    {
        HttpContext context = HttpContext.Current;

        if (context.Response.StatusCode == 302)
        {
            context.Response.ClearContent();

            // If Request is POST and Response is 302 and browser is Webkit use a refresh header
            if (context.Request.HttpMethod.Equals("POST", StringComparison.OrdinalIgnoreCase) && context.Request.Headers["User-Agent"].ToLower().Contains("webkit"))
            {
                string location = context.Response.Headers["Location"];
                context.Response.StatusCode = 200;
                context.Response.AppendHeader("Refresh", "0; url=" + location);
            }
        }
    }

    public void Dispose() 
    {} 
}

注意:我认为这不适用于非重载版本的Response.Redirect,因为它调用了Response.End()。