I recently started building a bookmarklet that displays the EXIF data of any image on a website. I chose to use Nihilogic's binary.js and exif.js libraries. For images hosted on the same domain as the parent page, the script works wonderfully. But because it uses XHR to read the binary data of images, and because XHR is restricted to same-origin requests, I can't access the binary data of any cross-site-hosted images.
Is there a way to load the binary data of an image locally (or at least without using XHR) that preserves EXIF data?
I've explored a few other directions, but I fear I don't understand them well enough to determine if there's a solution:
JSONP - I'm assuming there's no way to get binary data into one of these things.
canvas tags - these seem to produce very different base64 encodings than what PHP does, and I suspect that the EXIF data no longer exists in the new encoding.
Javascript is allowed to do special operations (like on the canvas) with same-origin images and cors-enabled images because the browser can safely assume that those would be OK to upload to the server in the first place. But then it gets complicated...
I can't access the binary data of any cross-site-hosted images.
Yes, generally it is very important that you can't. More to the point, you can't do what you want with a bookmarklet.
You can't do this with a canvas because the cors rules here are strict (for good reasons!)
In short the reasoning in general is pretty much exactly the same. Browsers are in a unique security position: A random page on the internet can show you things that are private to you, such as the hypothetical image, C:\MyPhotos\privateImage1.jpg, assuming it could guess that file path.
But that webpage is most certainly not allowed to do anything with that file other than show it to you. It can't read the binary information (EXIF information or pixel information). JavaScript is not allowed to know what that image looks like or nearly any data associated with it.
If it was able to figure that out, a random webpage would be able to try a bunch of file paths and maybe come across an image on your hard drive, and then upload the binary data of that image to a server, in effect stealing your private image.
A browser extension would be far more suited to this task than a (JavaScript) bookmarklet because of this.
Purely from the client? I doubt it. How about XHR'ing a local PHP script that runs something like exif_imagetype()? This function works on remote as well as images.
Related
I have an image stored in a different directory than my javascript, like so: "../part1/part2/part3/image.png"
If I try to render it to a canvas, then call getImageData on it, I get "The Operation is Insecure".
A cursory google search shows that this often happens for cross origin images. Which is all well and good, but it's my image, on my own server.
Is having a ".." in the path really enough to set the Cross Origin flag, or should I look for alternate causes for the message?
My objective is to have images stored in a parent directory that any of several different subdirectories (with their own html and javascript) can access. Is this a bad practice, and if so, are there alternatives?
Edit: Slightly more digging shows that local files are considered cross origin by default, which is indeed how I am testing. It's all well and good if this will work in production, but I want to test BEFORE putting it on my server. Any tips?
Edit: Yeah, I wasn't running a server. Guess there really isn't a better way then, huh?
Simperium looks like an awesome way to sync data across a variety of platforms and to deal with on/offline access from mobile.
For a project I'm working on some of the data is in the form of generated image and video files. I can't find any information about whether it is possible to sync this kind of data through Simperium (I guess I could base64 encode the images but it seems like a hack).
Or would I need to sync the URLs and then manually download these resources and somehow store them locally?
Simperium has basic support for binary files on the iOS side, currently in testing. This isn't yet available in the JavaScript library, but it will be. The way it works is similar to what you described. Simperium can handle the syncing of both a URL and its associated binary content in cases where that makes sense.
On iOS, binary files are stored to the local file system (though small files can indeed be stored as base64 encoded strings if you prefer).
In JavaScript, if you're working on the client side, the situation is less clear given the storage limits imposed by browsers, but you always have the option of syncing and using standard links depending on what you're trying to do. On the server side, there are of course more options. If you have some uses cases to share, you should get in touch.
I'm working on an image mashup web app.
I want to avoid flash or other client hassles and just do it pure HTML+javascript.
To keep it light, I'd like to do the work on the client side in Javascript, and have it just push a final saved image to the server.
I thought after reading about the wonders of HTML5 and Canvas I'd be able to use that.
Trouble is though:
If I use the new drag and drop feature of HTML5 for the user to pass a local image to the app and then paint it to the canvas, then ... the canvas get's dirty and it throws a security exception if I try to save the image data.
If I use an API like Bing Image search to find images for the user and paint them to the canvas, then ... the canvas gets dirty and it throws a security exception if I try to save the image data.
The only work around I can think is to have the server act as a kind of proxy and have it relay every image that is worked with to the client - but that defeats the purpose of going client side.
Is there any other method I'm not thinking of, or is pure HTML5 + JS at the client side just not an option for this use case?
The security exception is thrown because you are using images from different domain (local or Bing in your case), you should give to the user the ability to upload the selected images on your server and then work with them in canvas. For images from internet storages you can make something like a proxy to show them on the frontend, images from user's pc should always be uploaded. There is no other way to avoid XSS exceptions as far as I know.
P.S. there is a good article about HTML5 canvas image restrictions here: http://simonsarris.com/blog/480-understanding-the-html5-canvas-image-security-rules
I am stuck at a point where I am getting an image from the server as a binary data and i need to save this image on my PC without any user interference.
Think about it for a moment. If JavaScript could save files to your PC without your explicit consent, every hacker in the world would have access to your PC in a fraction of a second. Flash has enough security problems, JavaScript doesn't need them.
In other words, what you're asking for is impossible for good reason
Maybe the HTML5 File API is something for you. But without user action it would be a huge security hole!
http://updates.html5rocks.com/2011/08/Saving-generated-files-on-the-client-side
http://www.w3.org/TR/file-writer-api/#the-filesaver-interface
Why would you want to save something without user consent? That's never a good idea.
Anyways, JavaScript isn't able to mess with your computer's filesystem, thus it can't save the image to your hard drive. You could use JavaScript to create an image on your web page, using img or canvas, and then ask the user to save it, but exactly what you want is not possible with JavaScript.
On your server page, you could create the binary data, and set certain headers to treat the page as downloadable content, and that's about as close as you can get. It'd still ask for user consent, though.
Is it possible to dynamically create and modify images on a per pixel level in JavaScript (on client side)? Or has this to be done with server based languaged, such as PHP?
My use case is as follows:
The user opens webpage and loads locally stored image
A preview of the image is displayed
The user can modify the image with a set of sliders (pixel level operations)
In the end he can download the image to his local HDD
When searching in the web I just found posts about using IE's filtering method, but didn't find anything about image editing functions in JavaScript.
Some browsers support the canvas:
http://developer.mozilla.org/En/Drawing_Graphics_with_Canvas
This has to be done on the server side. One thing you might look at doing is allowing all the editing to go on client side, and then in the end POST the final image (via AJAX) to the server to allow it to return it to you as the correct MIME type, and correctly packed.
You may want to check out Processing.js. John Resig of jQuery fame wrote it. It supports pixel processing, unfortunately only Firefox 3 can handle it sufficiently.
Also look at data URIs (though IE versions below 8 don't support them, unfortunately!)
You can imagine a set of JS tools that will allow the user to define what kind of transformation he wants to do, but the final work of transformation MUST be done on a server side. JS on the client side is unable to create a file, for security reason.
Try Allicorn's Image Retargetter - it sounds like that's what you're looking for.
Local image manipulation in JavaScript should be possible - have a look at Defender of the Favicon. ;-) The question is how to get the original image from the file system into your page (I don't know of any other way than doing a HTTP upload to the server first).