views:

2296

answers:

9

I help moderate a forum online, and on this forum we restrict the size of signatures. At the moment we test this via a simple Greasemonkey script I wrote; we wrap all signatures with a <div>, the script looks for them, and then measures the div's height and width.

All the script does right now is make sure the signature resides in a particular height/width. I would like to start measuring the file size of the images inside of a signature automatically so that the script can automatically flag users who are including huge images in their signature. However, I can't seem to find a way to measure the size of images loaded on the page. I've searched and found a property special to IE (element.fileSize) but I obviously can't use that in my Greasemonkey script.

Is there a way to find out the file size of an image in Firefox via JavaScript?

Edit: People are misinterpreting the problem. The forums themselves do not host images; we host the BBCode that people enter as their signature. So, for example, people enter this:

This is my signature, check out my [url=http://google.com]awesome website[/url]!
This image is cool!  [img]http://image.gif[/img]

I want to be able to check on these images via Greasemonkey. I could write a batch script to scan all of these instead, but I'm just wondering if there's a way to augment my current script.

+1  A: 

You could set a maximum file size in your HTML where they upload files.

<input type="hidden" name="MAX_FILE_SIZE" value="10000000">

(max_file_size in bytes).

However, this is an "undocumented/unsupported" item of some browsers. You are best to actually check the filesize on the server once it's been uploaded.

You could also use a Flash or Java applet to handle the upload and check the filesize there. See http://www.masrizal.com/product/custom%20tag/cf_flashmultiupload/docs%20&amp;%20examples/example.cfm and http://www.saschawenning.de/labor/flash8/fileUpload/ for examples.

Richy C.
You misunderstand, people can link images from outside the forums. In fact, we don't host any signature images ourselves.
Daniel Lew
What browsers honour this?
alex
+2  A: 

As you know IE supports the fileSize property of an image. No such luck in other browsers ... however, you should be able to modify this script:

http://natbat.net/2008/Aug/27/addSizes/

It uses JSON to read HTTP headers of files and display their actual file size. That should help you prevent people uploading large animated GIFs.

As for getting the dimensions:

var img = new Image();
theImage.src = "someimage.jpg";
actualwidth = theImage.width;
actualheight = theImage.height;

This of course is a pure client-side approach to something best handled server-side.

Nissan Fan
People don't upload images to our servers. They link to images on other servers. If they are using dynamic images of some sort, then we can't validate the image size on the server.
Daniel Lew
A: 

Short answer, you cannot

Also, Check on jGuru How can you check the file size from JavaScript in a form with an input type of file?

You will find some important points

Amr ElGarhy
A: 

The DOM attribute img.fileSize will return the actual file size of the referenced <img>. Access to the img object can be obtained using JQuery or the DOM 'images' collection. However, this is an IE only extension.

Another approach is to omit the height and width attributes in the <img> tag, so that the full image is downloaded, then use img.height and img.width to determine the size of the downloaded image. This code could be put into the user's profile editor page as an intermediate step between having someone enter their signature as HTML, then showing them a preview of their signature. Clunky, I have to admit, but possible.

KeithL
Height and width are a bad measure for filesize, especially since the worst offenders are people who upload animated GIFs.
Daniel Lew
+2  A: 

Client side validation is insufficient to accomplish your goal. A simple post request will allow the user to upload any image they want no matter what html or javascript you serve them.

marr75
I don't think you understand what I'm asking, I updated the OP to better reflect the task at hand. (People don't upload anything to the server except code that points to images.)
Daniel Lew
A: 

If you are worried about huge images, set a max upload size as Richy C. mentioned, but also resize the uploaded image on the server and use the resized version.

Facebook does this for most of the uploaded images so that reasonably size images are served. Even converting them to png format in some (most?) cases, which drive the creative group nuts because of "lost quality".

A: 

What you should be able to do is an AJAX HEAD request of the image url, which just gets the header of the file rather than the contents, so is much faster. One of the headers you will get back is Content-Length, and that will tell you the size of the image in bytes.

More details here.

RedFilter
+1  A: 

Server side validation is always a better bet, but in your case, I can see why you would want to do this client side.

Also, it seems that others may have misread the question, and that the images that Daniel want to test are already uploaded, in which case there is a fairly simple method of doing so (provided the images are on the same domain as the script).

var getFileSize = function(address, responseHandler) {
  var req = new XMLHttpRequest();  

  req.open('head', address, true);  
  req.onreadystatechange = responseHandler;
  req.send(null);  
}

var responseHandler = function(resp) {
  if ( this.readyState == 1 ) {
    this.abort();
  }
  console.log(this.getResponseHeader("Content-length"));
};

getFileSize("http://stackoverflow.com/content/img/so/logo.png", responseHandler);

Boom. This example works in FF3 and probably 2. Since you're using Greasemonkey to do this, browser compatibility doesn't seem like an issue.

I'm not certain if Greasemonkey shares the same XML RPC domain restrictions, but if the images files that you need are on a different domain than the script, then you might need to look into using some iframe magic.

Justin Johnson
A: 

You can achieve exactly what you are after using the following API: http://www.filemd5.net/api a valid response will give you the exact filesize, and the API supports JSONP so making the calls cross domain won't be an issue.

JohnnieWalker