【问题标题】:WebKit image reload on Post/Redirect/GetWebKit 图像在 Post/Redirect/Get 上重新加载
【发布时间】:2010-11-29 06:37:40
【问题描述】:

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

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

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

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

有没有人找到解决这个问题的方法?或者有什么方法可以将影响降到最低?

谢谢。

【问题讨论】:

    标签: post redirect webkit get


    【解决方案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”重复。

    【讨论】:

      【解决方案2】:

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

      通过阅读 HTTP/1.1 规范,听起来 303 响应代码对于实现请求:POST、响应:重定向行为是正确的。不幸的是,更改状态代码不会使浏览器缓存在 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()。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-01-08
        相关资源
        最近更新 更多