Img HTML tag that does not execute the HTTP Refresh header (but loading the image URL in the browser)

I maintain a placeholder image with an HTTP Refresh header, for example:

Connection:keep-alive Content-Type:image/gif Date:Thu, 01 Aug 2013 14:16:25 GMT Refresh:10; url=/media/thumbs/document/18.png Server:nginx/1.4.1 Transfer-Encoding:chunked 

If I load the image placeholder URL in the full window, the content is updated after 10 seconds, but if I put the same URL in the src property of the image tag, the image will never be updated (checked in Chrome and FF).

Why am I doing this? I have an application where a sketch of a document takes a few seconds, which must be generated by the server (this is a complicated SVG rendering). When the user goes to the list of documents immediately after creating a new document, the thumbnail does not yet exist. I tried using the placeholder image with the update header to load the real thumbnail in a few seconds.

I can’t remember how, but back in the good old days of the Netscape browser, something like an update header is how we sometimes cracked the animation (it was before Flash - am I prehistoric or what?). We called it "server push" (I think the buzzword was redesigned using the comet model ).

I use Angular.js on the client side (on the server side Django + uWSGI + Nginx), so it should be easy to hack something using javascript, but I'm curious: is there any trick (without javascript) for the image tag to load another source in a few seconds?

(I will mark this Django and Nginx, because maybe someone knows the server solution)

+6
source share
3 answers

Explanation

When you open the image directly in the browser, it ends as an HTML document.

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

In Chrome, you will 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 "packaging" is not performed for the src IMG tag that are inside the document.

Decision

If you intend to use only HTTP headers, you are stuck in multipart / x-mixed-replace described by @JamesHolderness, but pay attention to leaving HTTP connections open as this can damage your performance server and potentially open you up for a DDoS attack.

I was going to suggest using CSS animations / switching to lazy image loading. Unfortunately, only Chrome supports a background image (CSS property). Another option: display: no, because the image does not load until the element is displayed, but no browser supports animation or transition to the screen (CSS property).

Here only Chrome, only CSS 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 SVG SVG data as the background image you need, you can bypass the Chrome parser for preloading the image.

SVG example

 <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,=='); 
+1
source

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

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

For your actual content, you start by recording placeholder images as follows:

 --myboundary Content-Type: image/jpeg Content-Length: <size of the image in bytes> <binary image data + CR/LF> 

Then immediately clear the output, but keep the connection on the network (i.e. it will use encoded transfer coding).

Now you can start generating your svg, and when it is finished, write it as follows:

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

Basically it works streaming M-JPEG , only in this case the frames are not all jpeg images.

+3
source

You can try putting your image in an iframe and returning the page for that iframe with the Refresh heading.

But seriously, use JS.

0
source

Source: https://habr.com/ru/post/950837/


All Articles