Store data from image in a cookie - javascript

I am trying to store image in a cookie, but I don't know if this is the best way keep registers from a user when he refreshes the page.
Well, I am using ngCookies module to do that. So I received a image from server in base64 string format, the contentType and the data and then I store in the cookies:
$cookies.contentType = value.image.contentType;
$cookies.data = value.image.data;
To make my url I do this:
vm.url = "data:"+vm.value.image.contentType+";base64,"+vm.value.image.data;
And the url I insert in my page, using img html:
<img src={{ctrl.url}} style="width:200px;height:200px">
My problem is: when I refreshed my page, $cookies.contentType remains, but value.data doesn't stay stored in $cookies.data anymore. I think this value is too big to store in a cookie. I am using cookies correctly? Are there other way to do that?
I appreciate if anyone can help me.

Using cookies for client side storage is generally considered to be less than ideal. Cookies are automatically sent back with every request (if it matches domain/path/security restrictions). Even if the cookie storage limit could handle this I can't imagine you would want to send this back with any future request. LocalStorage and similar technologies were developed in part to avoid this issue.
That said, the http cookie spec originally stated that a cookie needed to accommodate at least 4096 bytes which was then generally interpreted as setting a max size of approximately 4k. Each browser handles this a bit differently and there are plenty of places to read up on it.

Related

HTML hidden input shouldn't be editable

I just discovered a bug which I couldn't find any solution of, I would like your advise on that. Issue is there are a few hidden input types, which are there to store ID's of already saved data such as per person id if it is already saved etc. etc.
I just tried and change the value of that hidden variable manually, using google chrome and submit the form and surprisingly i did not get the id that should be there but instead i received the Id that I changed. for instance there was an value of 22 I change it 263 I received 263, whereas I should have be receiving 22. I want that 22 to come not that 263.
Its hard to explain I know but I have tried my level best to convey my issue please help and advise my on that how should I store some hidden value that are un-editable.
Any Idea?
Rule of Web Development #1: Never trust the client
Rule of Web Development #2: Never trust the client
Rule of Web Development #3: You can't make the client trustworthy
If the user shouldn't be able to edit it, never give it to them.
As others have said, there are a few ways to handle the situation. The most common is to use a SESSION variable on the server, available almost everywhere.
Store the "secret" values on the SESSION. They will be available when the user posts back.
You cannot control what data users put in HTTP requests to your server.
Instead, use authentication and authorization, on the server, when the request is received, to make sure that the user is allowed to submit the values they submit.
If you're wanting to keep track of data from one page to another I would use sessions. This is data that is tracked on the server.
//page one.php
$_SESSION['id'] = 22;
//page two.php
echo $_SESSION['id']; //22
This is a basic functionality of how browsers work - essentially someone could POST data pretending to be your form with whatever values they wanted in the fields - or even add extra fields.
If it's a problem consider moving that data from hidden fields to session variables.
If it's important for your hidden fields to be secure, don't contain them on the client-side. Client side variables are pretty easy to modify.
You should probably store them in your session, so they're not outputted to the client. If they're required on the page, use AJAX to grab them instead.
It kinda depends on the domain of your application, if it's in-house software then I wouldn't worry about it particularly.
It does not look like a bug.
What scares you about this? These fields are not going to be accessed and changed by your visitors. If you're afraid someone is going to hack the http request of your visitor and change his order (for example), then https connection should help.

Reliable file caching

I'm trying to determine the best way to cache my JavaScript and CSS files.
There are several ways of doing this:
Using the Date, Expires and Cache-Control headers
Using the ETag header
Cache forever and change the filename when the file changes
Append a querystring to the filename in the HTML with the last mod time or an MD5 of the file contents
I was under the impression that the last method (4) was the most reliable and would result in the fewest unnecessary requests, but my friend just told me that sometimes the querystring method is unreliable and you actually need to change the filename.
Are there any downsides to setting the HTTP headers to cache forever and just using a query-string with the last mod time, or are there scenarios where another method would be more beneficial?
I'm a big fan of method 4, but I use the Session Id, on it. So, a user that enters my website will load it once per session (a session usually dies if the visitor keeps inactive for more than 20 minutes or if he closes the browser window).
In Asp.net, I use that syntax:
<script src="js/DetalhesCurso.js?<%=Session.SessionID%>"></script>
Your third method is the most reliable. Some CDNs/proxies ignore the query string altogether, and just serve the same cached file regardless of the query string value.
Amazon and Azure do support it, but others might not.
Do note that in method #3 you don't actually have to update the filename itself. You can just use some URL rewriting to always get that same file. You'll only have to update your HTML.

Canvas Image to an Image file

So i have a canvas on which the user signs, now instead of converting it to a base 64 string i simply want to save it as an image itslef. whats the easiest way to do it html5??
You can easily do that this way (specifying the format as png in this case):
var img = canvas.toDataURL("image/png");
You can specify different image formats.
Take a look at this answer.
I've answered a similar question here:
Simulating user event
Assuming you are saving locally
You can go the route of creating an image from a Data URL, but then saving it is the trickier part that currently isn't very nice using HTML5. It's hopefully going to get better soon, if browsers incorporate the download attribute of the a tag.
Obviously if you have higher permissions than a standard webpage... i.e. you are designing a browser plugin - then there are other options...
If I were to implement something like this myself, at the moment, I would conceed to using a flash plugin to handle the save to the local computer.
Assuming you are saving remotely
By the sounds of it you aren't saving to a server, but if so this is quite easy by just POSTing the base64 information to a script written in a server-side scripting language (i.e. like PHP) and getting that to write the data directly as binary to a file. Obviously you have to make certain you do this securely however, you don't want just any binary data written to your server's filesystem.
Best of both worlds
If you've got the development time, the best method to get a canvas image saved locally - without Flash - is to create a server-side script that instead of saving the data to your server actually writes the Base64 information you send it directly back as a realised binary image file. That way you can create a form that posts your Base64 data to a new tab, this request is evaluated by the server-side, and the binary image is returned... at which point the browser asks the user where they wish to save their image.
You'll need to define the correct headers to force an image to download (rather than display in-browser). A simple change to force this is to set the server-side script's Content-type header to 'image/octect-stream'... there are other header options to set which would be best researched (i.e. headers that control the filename and so forth).
reflect.php
<?php
/// a simple example..
if ( array_key_exists('data', $_POST) && ($data = $_POST['data']) ) {
header('Content-type: image/octet-stream');
echo base64_decode( $data );
exit;
}
and the form...
<form action="reflect.php" method="post" target="_blank">
<input name="data" type="hidden" value=" ... Base64 put here with JS ... ">
</form>
(The whole form should be created dynamically and submitted automatically with JavaScript)
Improving the user experience
There are ways to avoid a new tab being created, but you'd have to research to make sure these other methods don't cause cross-browser problems... for example you could post your form data as part of an iframe (which would keep the process hidden), or just post the data directly on the current window (..and hope that all the browsers receive the correct request and open a download rather than replace your page content - most modern browsers should handle this).
Improving security
With regards to a PHP script that automatically returns binary data, you should keep the access to this script secured by one time use key / authentication token or something similar, and keep a limit on how much Base64 data you are willing to accept. It might not seem like it poses a secutiry risk - as you are not modifying your server in any way with what the user sends - but the dodgy people of this world could take your script and use it to send download request to other users... which if downloaded (and turned out to be unwanted trojans or viruses) would make your server implicit in providing the dodgy file.
All in all
Due to the effort required to get a simple thing like an image saved to the desktop, I wouldn't blame you for doing the following:
Embed the image in the page (after taking your snapshot from canvas) and ask the user to right click and Save as...
Hopefully future things will make this situation better...

Refresh image or clear cache

Is there any way (server or client side) to force the browser to pull a new version of a file (image) from the server. The image in question is otherwise cached for a long time. I know I can append a random number, for instance, to the URL of the image but this is not acceptable in this situation. I need for the image to be refresh from the exact same URL.
What I'm doing: a YouTube like portal where users upload videos. Each video has a thumbnail which is shown on various pages on the portal. User can, at any time, change the thumbnail (he can select from three generated thumbnails). So when this happens (a new image overwrites the 'original' image), I wan't to refresh the video's thumbnail so that the owner (I don't care if other users see the old thumbnail) will see the new thumbnail no matter where the thumbnail is shown.
I'm afraid this can't be done but I'm asking here just to be sure.
update: I'm using nginx and PHP on the server side
You could use ETAGs on your thumbnails. This would prevent the transmission of the actual thumbnail data if it hasn't changed (i.e. still has the same hash). However, you would still face the clients HTTP requests to check if the ETAG has changed (normly to be answered by HTTP 304.
But combined with a rather short freshness threshold (say a couple of minutes), you could achieve tradeoff between caching and freshness while still conserving resources. If you need absolute freshness, you might have to stick to ETAGs though. If you create a clever hash function, you could handle the ETAG requests on your frontend loadbalancer (or at least near it) which could thus be rather cheap.
Edit: Add alternative from my other comment.
An alternative could be to use added request parameters to force a re-fetch when the resource changed as suggested in another answer. A variation of that schema (which is used by many Rails applications) is to append the timestamp of the last change (or some kind of hash) as a parameter to the file which only changes when the file actually does change. Something like this, or one of the above methods, is actually the only way to be really sure to not have unnecessary cache validation requests while at the same time having always the freshest resource.
Add at the end of the filename a get parameter, such as:
example.jpg?refresh=yesplease
You could also refresh that image each visit by using a rand() param.
In php:
example.jpg?refresh=<?php echo rand(1,999); ?>

Persist javascript variables between GET requests?

ASP .NET is allowed
Storing the values in hidden input fields is allowed
Query String is not allowed
POST request is not allowed
It is possible to store JS variables between GET requests ?
I want to reinitialize them on the client using ClientScript.RegisterStartupScript
Can I use cookies for this ?
Are there other posibilities?
Where cookies are stored when Request is made ?
Can I use cookies for this ?
Yes, see this tutorial on using cookies in Javascript.
Are there other posibilities?
If you are not allowed to append anything the URL of your requests, I can't come up with any.
Where cookies are stored when Request is made ?
In the HTTP request header. The aforementioned tutorial will tell you how to read their values from Javascript. On the server side with ASP.Net, you can read cookie values using Request.Cookie["cookieName"] which returns an instance of HttpCookie.
I wouldn't highly recommend this, but the other option is to alter the window.name property.
You can save some minor bits of data here, then retrieve them on the next page load.
Pros:
Quick-n-dirty, but works
Cons:
Messes up any window references for popups/child iframes
Since its a "hack", browser vendors may break this "feature" in the future
Of course if you can exclude all the old browsers, then use Global/Client Session Storage!
At the moment using cookies is your best bet. You can serialize the JavaScript objects to strings, and unserialize them back into objects later. A good choice format is JSON, since it is a subset of JavaScript.
There is also storing objects in Flash.
Storing in Google Gears.
DomStorage
See this library that has an interface to each:
http://pablotron.org/?cid=1557
If you are in control of all aspects of the page, then you can also wrap the page in a top level frame. Then only refresh the child frame. You can then store content in the parent frame.
You can see this used in sites like GMail, and others where the only thing that changes in the URL is outside the #.
You don't even have to change the URL, that part is just put in for Human Friendly URLs. (So you can actually copy and paste URLs as is).

Categories