img HTML tag not honoring the HTTP Refresh header (but loading image URL in the browser does) img HTML tag not honoring the HTTP Refresh header (but loading image URL in the browser does) nginx nginx

img HTML tag not honoring the HTTP Refresh header (but loading image URL in the browser does)


If you don't need to support IE, and your svg generation doesn't take so long that it would cause a connection to timeout, you can achieve a similar effect using a Content-Type of multipart/x-mixed-replace. Something like this:

Content-Type: multipart/x-mixed-replace; boundary=myboundary

For your actual content, you start by writing out the placeholder images like this:

--myboundaryContent-Type: image/jpegContent-Length: <size of the image in bytes><binary image data + CR/LF>

Then immediately flush the output, but keep the connection alive (i.e. this will use a chunked Transfer-Encoding).

Now you can start generating your svg, and when it is finished, write it out like this:

--myboundaryContent-Type: image/svg+xmlContent-Length: <size of the image in bytes><svg image data + CR/LF>--myboundary--

This is basically how streaming M-JPEG works, only in this case the frames aren't all jpeg images.


Explanation

When you open an image directly in the browser, it's wrapped up as an HTML document.

Go to google's latest doodle jpg then open up your HTML console (http://www.google.com/logos/doodles/2013/erwin_schrdingers_126th_birthday-2002007-hp.jpg).

In Chrome you'll get:

<html><body style="margin: 0px;"><img style="-webkit-user-select: none" src="http://www.google.com/logos/doodles/2013/erwin_schrdingers_126th_birthday-2002007-hp.jpg"></body></html>

This "wrapping" isn't done for IMG tag src's that are inside of a document.

Solution

If you are intent on using just HTTP headers you're stuck with the multipart/x-mixed-replace described by @JamesHolderness, but note leaving HTTP connections hanging open like this can hurt your server performance and potentially open you up to a DDoS attack.

I was going to suggest using CSS animation / transition to lazy load an image. Unfortunately only Chrome support background-image (CSS property) animation. Another option would of been display: none since the image doesn't load until the element is displayed, but no browser supports animating or transitioning on the display (CSS property).

Here's the Chrome only, CSS only solution http://jsfiddle.net/r2Tag/

HTML

<div id="thumbnail"></div>

CSS

#thumbnail {    position: relative;    width: 475px;    height: 184px;    background-image:url('http://lh3.ggpht.com/Z9Bl8P_zqvnB_FPBw5PqZlHelALdwWoBV5EZSEVI85kS698xDzghSmLzREcaS1Uh31L5PIRdAiuMUcBSNlBGCsc-9YshQaxnMA4uzU2c-Q');    animation: loadthumbnail 0s linear 10s;    -webkit-animation: loadthumbnail 0s linear 10s;    animation-fill-mode: forwards;    -webkit-animation-fill-mode: forwards;}@keyframes loadthumbnail { to {    width: 491px;    height: 190px;    background-image:url('https://www.google.com/logos/doodles/2013/erwin_schrdingers_126th_birthday-2002007-hp.jpg');} }@-webkit-keyframes loadthumbnail { to {    width: 491px;    height: 190px;    background-image:url('https://www.google.com/logos/doodles/2013/erwin_schrdingers_126th_birthday-2002007-hp.jpg');} }

EDIT If you use a data URI SVG as the background-image you animate to you can circumvent Chrome's parser pre-loading the image.

Example SVG

<svg x="0px" y="0px" width="491px" height="190px" viewbox="0 0 491 190" xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink"><image externalResourcesRequired="true" xmlns="http://www.w3.org/2000/svg" x="0%" y="0%" height="100%" width="100%" xlink:href="https://www.google.com/logos/doodles/2013/erwin_schrdingers_126th_birthday-2002007-hp.jpg" xmlns:xlink="http://www.w3.org/1999/xlink"/></svg>background-image: url('data:image/svg+xml;base64,PHN2ZyB4PSIwcHgiIHk9IjBweCIgd2lkdGg9IjQ5MXB4IiBoZWlnaHQ9IjE5MHB4IiB2aWV3Ym94PSIwIDAgNDkxIDE5MCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB2ZXJzaW9uPSIxLjEiIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIj48aW1hZ2UgZXh0ZXJuYWxSZXNvdXJjZXNSZXF1aXJlZD0idHJ1ZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4PSIwJSIgeT0iMCUiIGhlaWdodD0iMTAwJSIgd2lkdGg9IjEwMCUiIHhsaW5rOmhyZWY9Imh0dHBzOi8vd3d3Lmdvb2dsZS5jb20vbG9nb3MvZG9vZGxlcy8yMDEzL2Vyd2luX3NjaHJkaW5nZXJzXzEyNnRoX2JpcnRoZGF5LTIwMDIwMDctaHAuanBnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIvPjwvc3ZnPg==');


You may try to put your image into iframe, and return a page for that iframe with the Refresh header.

But, seriously, use JS.