Obtain inline image filesize (Javascript?)

learning_brain

New Member
Messages
206
Reaction score
1
Points
0
On my image search engine site, I have several pages that use hotlinked images from other sites (yes still - sorry to users who know this already, I have not found an adequate solution).

Many sites now use the hotlink breaker: showing an alternate image in its place...understandable.

I would like to be able to run a script client-side to determine the filesize of the image parsed in the browser and check against the stored original filesize.

If they don't match, I can offer an alternate link.

My problem is... I'm not too hot with JavaScript and I can't use a server-side script because the server will pick up the right filesize.

Has anyone got any ideas how to get filesizes of inline images?

Any help appreciated.

Richard
 

descalzo

Grim Squeaker
Community Support
Messages
9,373
Reaction score
326
Points
83
Really don't think there is a way to do what you want.
 

misson

Community Paragon
Community Support
Messages
2,572
Reaction score
72
Points
48
It doesn't even make sense to ask for the file size of an image element, because the image that appears in a document has been decoded, and doesn't have a file size. The only size-related properties you can access are the width and height.

You might be able to do something with Flash, or by making a HEAD request with AJAX.
 

learning_brain

New Member
Messages
206
Reaction score
1
Points
0
It doesn't even make sense to ask for the file size of an image element, because the image that appears in a document has been decoded, and doesn't have a file size. The only size-related properties you can access are the width and height.

You might be able to do something with Flash, or by making a HEAD request with AJAX.

Didn't realise that - thank you.

Width and height would be fine but, as I said, javascript is not my best subject - any pointers?
 

learning_brain

New Member
Messages
206
Reaction score
1
Points
0
Thanks Misson

I'm starting to learn some very basic javascript for this but don't know how to mix JS with php - i.e. how to compare a php variable with a javascript variable.

This is where it's doing my head in because I assume they cannot compare due to the fact that one is server-side and one is client side. In other words, a database variable, echo'd with php is presumably parsed in Apache before javascript even starts working. Is this where the AJAX comes in?

so far - all I have is..

Code:
var img = new Image();
	img.onload = function() {
	  var w = img.width;
	  var h = img.height;
	  alert( 'The size of the image is '+ w +'x'+ h );
	}
	img.src = 'img absolute url'

Funny!

Rich
 

misson

Community Paragon
Community Support
Messages
2,572
Reaction score
72
Points
48
I'm starting to learn some very basic javascript for this but don't know how to mix JS with php - i.e. how to compare a php variable with a javascript variable.
It's not very helpful to think of "PHP variables" and "JS variables". There's just code and data, and there isn't always a difference between the two. It can be helpful to think of host and embedded languages when dealing with documents that mix languages.

StackOverflow has many questions on how to pass data from PHP to JS and JS to PHP; start there. The gist is that you pass data between client and server the way you always do: in requests. You just have to decide on the format, and convert the data to that format for the request. PHP or whatever server-side technology you're using can generate resources of any type: HTML, JS, JSON, XML, CSS, images... You can simply have a PHP script generate the JS, either embedded or external. In the latter case, give the script an extension of ".js.php" and use some form of clean URLs, and the client doesn't even have to be aware that the JS is generated. Just make sure you set the Content-type header properly, and pass any data (including strings) through json_encode before outputting:

PHP:
<?php
header('Content-type: application/javascript'); 

$img = array('w' => 230, 'h' => 170);
?>
var img = <?php echo json_encode($img); ?>;
/* img == {w: 230, h: 170} */

Going from client to server, you can send a GET request and use query parameters, or POST (or PUT) the data and format it as x-www-form-urlencoded, JSON, XML or some other format (JSON is a nice mix of simple & powerful). You can use a form to send the request, or a link (limited to GET requests; use JS to generate the query string), or AJAX techniques (XMLHttpRequest or a hidden IFRAME), perhaps encapsulated in a JS library.

More on XMLHttpRequest:

This is where it's doing my head in because I assume they cannot compare due to the fact that one is server-side and one is client side. In other words, a database variable, echo'd with php is presumably parsed in Apache before javascript even starts working.
It depends on where in the document it's output. Note that Apache doesn't parse anything; it merely handles requests, possibly passing them off to a module or external process. PHP parses PHP, browsers parse HTML (and CSS) and hand off JS to their built-in JS engine.

Is this where the AJAX comes in?
Sort of. AJAX (Asynchronous JS And XML) lets you send a request without (re-)loading a page. You use JS to send the request. Originally, the response would be XML, but these days HTML and JSON are more common. The "asynchronous" is because the JS function call is, well, asynchronous–it returns before the (remote) computation is complete.

You don't need to use AJAX to submit data to a PHP script; you can simply submit as normal and let the page reload. AJAX can break the browser model (history and bookmarks, for example), so it should be used only when the browser model doesn't apply or when you can fix the break.
 
Last edited:

learning_brain

New Member
Messages
206
Reaction score
1
Points
0
Thanks Misson.

There's a whole heap of stuff in there to understand... and learn! I do understand AJAX to a degree and use it regularly on the site for button functions. I'm not sure I need to do that here.

I have developed my original js code to the following:

Code:
<script type="text/javascript">

	//function to replace image content
	function ReplaceContentInContainer(id,content) {
		var container = document.getElementById(id);
		container.innerHTML = content;
	}
	
	//check image in browser is the same as the harvested original
	var img = new Image();
	img.onload = function() {
	  
		var w_actual = img.width;
		var h_actual = img.height;
		var w_shouldbe = <?php echo $row_MainImage['WIDTH'];?>;
		var h_shouldbe = <?php echo $row_MainImage['HEIGHT'];?>
		
		if(w_actual == w_shouldbe && h_actual == h_shouldbe){
			//do nothing
		} else {
			ReplaceContentInContainer("image_container","<img src='includes/get_image.php?imgSRC=<?php echo $row_MainImage['IMAGEURL'];?>' alt='<?php echo resolveKeywords($row_MainImage['KEYWORDS'],$row_MainImage['IMAGEURL']);?>' width='<?php echo $row_MainImage['WIDTH'];?>' height='<?php echo $row_MainImage['HEIGHT'];?>' border='0' />");
		}
	  
	}
	img.src = '<?php echo $row_MainImage['IMAGEURL'];?>';


</script>

<div id="image_container">

	<img src="<?php echo $row_MainImage['IMAGEURL'];?>" alt="<?php echo resolveKeywords($row_MainImage['KEYWORDS'],$row_MainImage['IMAGEURL']);?>" width="<?php echo $row_MainImage['WIDTH'];?>" height="<?php echo $row_MainImage['HEIGHT'];?>" border="0" />

</div>

Please understand that my understanding of javascript is VERY limited so this probably appears very messy - but it works beautifully.

Page loads... image dimensions are obtained and compared with what they should be... if result is not equal, use of innerHTML to change the content of the image div, including an alternative source (which is a php imagecreatefrom...)

I had to use innerHTML due to the problems with document.write inside the function - which apparently reloads the page??


Thoughts to improve?

Richard
 
Last edited:

misson

Community Paragon
Community Support
Messages
2,572
Reaction score
72
Points
48
Make sure you encode date in in the proper format when outputting it. For example, use json_encode for JS data (since PHP's output format for numbers is already valid JS, you can skip the encoding for such, but for anything else (from bools to arrays), encode it) and htmlspecialchars for HTML attributes. This will properly handle any metacharacters that pop up in the data (and that could be the source of injection).

Code:
img.src = <?php echo json_encode($row_MainImage['IMAGEURL']) ?>;
HTML:
<img src="<?php echo htmlspecialchars($row_MainImage['IMAGEURL']) ?>" />

I had to use innerHTML due to the problems with document.write inside the function - which apparently reloads the page??

document.write is very outdated. innerHTML works these days on the major browsers, but it's not standardized, so there's no way of telling what its future will be. The DOM methods (e.g. Document.createElement, Node.insertBefore and Node.appendChild) are the modern way of manipulating a document. Many JS libraries offer convenience methods that wrap around whatever manipulation methods the browser offers, which both shortens the code you have to write and relieves you from keeping the code up to date.

In this case, you don't need to replace any elements. Instead, you can change the attributes of the existing <img> element directly; in particular, set src on the image element.

Code:
/* you can use this function for any image on the page */
function fixHotlinkBreaker(img) {
    var testImg = new Image();
    testImg.onload = function() {
        if (testImg.width != img.width || testImg.height != img.height) {
            img.src = 'includes/get_image.php?imgSRC=' + img.src;
        }
    }
    testImg.src = img.src;
}

fixHotlinkBreaker(document.getElementById(...));

Off-topic, "includes/get_image.php" looks like a very dirty URL, too dependent on implementation. Even from an internal, implementation standpoint, an "includes" directory should only hold library files (which only define things), not any script that executes code directly, and certainly not any entry point. URLs are the nouns of HTTP; "get_image" is a verb. Instead, design your URLs to reflect a hierarchy of names, which is where you get URLs that start with "/images", "/videos", "/style", "/scripts" and the like. Here, you could have something under the "/images" hierarchy, then rewrite it to whichever internal structure you've implemented.
 
Top