WebKit image reload on Post/Redirect/Get

2019-09-06 13:47发布

We just redesigned a web application and as a result we've noticed a bug in Chrome (but it supposedly affects all WebKit browsers) that causes a full image/js/css reload after a Post/Redirect/Get. Our app is built using ASP.NET and uses a lot of Response.Redirect's which means users will run into this issue a lot. There's a bug report for the issue with test case: https://bugs.webkit.org/show_bug.cgi?id=38690

We've tried the following to resolve the issue:

  • Change all Response.Redirects to be JavaScript redirects. This wasn't ideal because instead of images reloading, there would be a "white flash" during page transitions.
  • We wrote our own HTTP handler for images, CSS and JS files. We set it up to where the handler sends a max-age of 1 hour. When the client requests the file again, the handler checks the If-Modified-Since header sent by the browser to see if the file had been updated since the last time it was downloaded. If the dates match, the handler returns an HTTP 302 (Not Modified) with 0 for the Content-Length. We ran a test where if the image was downloaded for the first time (HTTP 200), there was a delay of 10 seconds. So the first time the page loaded, it was very slow. If the handler returned 302 (Not Modified), there was no delay. What we noticed was that Chrome would still "reload" images even when the server returned a 302 (Not Modified). It's not pulling the file from the server (if it were, it would cause a 10 seconds delay), but yet it's flashing/reloading the images. So Chrome seems to be ignoring the 302 and still reloading images from it's cache causing the "reload".

We've checked big sites to see if they've fixed it somehow, but sites like NewEgg and Amazon are also affected.

Has anyone found a solution to this? Or a way to minimize the effect?

Thanks.

2条回答
对你真心纯属浪费
2楼-- · 2019-09-06 14:04

I ran into this problem myself with an ASP.NET web forms site that uses Response.Redirect(url, false) following a post on many of its pages.

From reading the HTTP/1.1 specification it sounds like a 303 response code would be correct for implementing the Request: POST, Response: Redirect behavior. Unfortunately changing the status code does not make browser caching work in Chrome.

I implemented the workaround described in the post above by creating a custom module for non-static content. I'm also deleting the response content from 302's to avoid the appearance of a blink of "object moved to here". This is probably only relevant for the refresh headers. Comments are welcome!

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() 
    {} 
}

Note: I don't think this will work with the non-overloaded version of Response.Redirect since it calls Response.End().

查看更多
再贱就再见
3楼-- · 2019-09-06 14:12

This is a bug. The only "workaround" I've seen untill now is to use a Refresh header instead of a Location header to do the redirecting. This is far from ideal.

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

Also, this question is a duplicate of "Full page reload on Post/Redirect/Get ignoring cache control".

查看更多
登录 后发表回答