documentcloud / document-viewer

The NYTimes Document Viewer
http://open.blogs.nytimes.com/2010/03/27/a-new-view-introducing-doc-viewer-2-0/
Apache License 2.0
690 stars 120 forks source link

Images loaded twice #26

Open MattJones opened 11 years ago

MattJones commented 11 years ago

I'm running an embedded docViewer that pulls images from Rails. I put a debug output statement in the image-return controller action. On first load, it reports just one request for each of the first 3 pages. Each page loaded after that generates 2 requests and gets 2 full responses from rails. One request is coming from DV/lib/page.js#drawImage.js, but I don't know where the other comes from. The page doesn't load until the second request completes.

Is this behavior intended? Is there a way to limit it to a single request?

knowtheory commented 11 years ago

Hey Matt, is this something you're only seeing in your rails logs, or do you also see two get requests in the chrome/firefox/safari inspectors too?

MattJones commented 11 years ago

Hi Ted,

Thanks for your response. I'm seeing it twice in my rails logs and in the chrome network console.

I've been playing around with it, and noticed that the image doesn't update until the second request completes. I tweaked rails to respond with a 500 error for a duplicate request, and the resulting error came from a jquery source. I tracked the stack trace back, and that call that failed originated from the call to replaceWith in lib/page.js#drawImage. That makes me think this might be from my newer jquery (1.7.2) versions interfering with the jquery version included with documentViewer (1.5.1).

-Matt

On Tue, Mar 26, 2013 at 4:22 PM, Ted Han notifications@github.com wrote:

Hey Matt, is this something you're only seeing in your rails logs, or do you also see two get requests in the chrome/firefox/safari inspectors too?

— Reply to this email directly or view it on GitHubhttps://github.com/documentcloud/document-viewer/issues/26#issuecomment-15485987 .

Matthew Jones Software Engineer logik.com (703) 785-6702 (mobile) (202) 250-3686 (office) (800) 951-5507 (toll free)

NEW! We've moved! Our freshly designed office is at 1400 I Street NW Suite 800, Washington DC 20005. Please update your records and by all means swing in for a visit.

brentroady commented 10 years ago

This seems to only occur in Chrome. In lib/page.js#loadImage, the line

preloader[0].src = src;

sets the src on the img tag and causes the browser to make a request to load the image. The preloader load event handler then calls drawImage, which has

this.pageImageEl.replaceWith('<img width="'+this.model_pages.width+'" height="'+imageHeight+'" class="DV-pageImage" src="'+imageURL+'" />');

In Chrome this causes another request to be sent. A second request was not sent in Firefox or IE.

For most people with static images, the web server probably handles this second request with a 304 response. I am generating images dynamically, so I added code to explicitly handle this.

MattJones commented 10 years ago

@brentroady: I'm dynamically generating the images as well. Can you post a sample of your code for how you handled the double request?

brentroady commented 10 years ago

My server code is in Asp.Net MVC instead of Rails, but it can probably be translated pretty easily.

var lastModified = DateTime.Now.ToUniversalTime();
var modifiedSince = Request.Headers["If-Modified-Since"];
if (!string.IsNullOrEmpty(modifiedSince))
{
    DateTime modifiedSinceDate;
    try
    {
        modifiedSinceDate = DateTime.Parse(modifiedSince).ToUniversalTime();
        if ((lastModified - modifiedSinceDate) <= TimeSpan.FromSeconds(60)) // Cache for 60 seconds
        {
            return new HttpStatusCodeResult((int)System.Net.HttpStatusCode.NotModified);
        }
    }
    catch (Exception) { }
}

Response.AddHeader("Last-Modified", lastModified.ToString("R"));
// Code to generate and return image here

Comparing the If-Modified-Since header in the request to the current datetime and returning a 304 if older than a certain elapsed time. Then setting the Last-Modified response header for when generating the image. Hope this helps!