Downloading file from local storage - javascript

is anyone aware how to properly "exploit" the local browser storage to "cache" chunks of data, assemble them and prompt a download?
I'm currently using the method where data is stored encoded in B64, and passed to an <a> element constructed on the fly and the target set to a data URI; I don't feel like this is the right method in case of big files (>5Mb) and not tested it so far.
I'm also aware that Mega does something similar, but it's unclear to me how they do it and how to properly recreate that.
In case anyone is wondering, the data is transferred via websocket to the browser.

Related

HTML Object data URL from dynamic source

So all uploads for my app are not stored in my web server space, they are stored in a file system storage. When my users want access to the file they call a URL and the backend process will buffer the data to the browser via the HttpServletResponse outputstream. This works great as intended for downloading a file. Now my use-case has a scenario where I need to load an embedded object using this same method.
I am essentially loading a preview of the PDF file in the browser. This works fine if the PDF is stored on the web server and I provide a direct URL to the file. But when I use my method of sending files to the user then it doesn't work.
<object data='"+pdfUrl+"' type='application/pdf' width='160px' height='160px' />
If i put pdfURL into a browser my file gets downloaded no problem. So I think the issue is the HTTP headers I am sending in the outputstream that maybe is preventing the Object from loading properly. I am not sure if maybe its expecting something specific to be set in order to trigger loading the file
I am currently using very basic headers as follows:
BufferedInputStream is = <Some File Inputstream>;
resp.setContentType(new MimetypesFileTypeMap().getContentType(directory+filename));
resp.setHeader("Content-Disposition", "attachment; filename="+StringFormatHelper.formatFileName(filename));
bufferedCopy(is, resp.getOutputStream());
is.close();
resp.getOutputStream().flush();
Anyone have any ideas on what I have to change to get the data to properly load in the Object tag? I don't get any errors in the JS console or server side. I am not sure how to debug this issue.
Edit:
SO i just realized that if i right click on where the blank Object tag is at I have the option to "Save as..." and when I do I download the PDF. So the pdf data is loaded but Its just not displaying in the UI.
The issue is this line of code
resp.setContentType(new MimetypesFileTypeMap().getContentType(directory+filename));
This was not setting the correct mime-type for the file as I thought it was. So there was a mismatch in that the Object tag was looking for application/pdf but the server was sending a different MIME type in the header. Once I matched them up everything worked.
I was able to get the correct MIME type using the Spring provided lookup instead of the JDK lookup
new ConfigurableMimeFileTypeMap().getContentType(directory+filename)

Drag File in Data URI format from Browser to Desktop

As this blog post points out, there is a way to download files via drag and drop from browser to desktop.
I want to drag a file in data uri format (e.g. "data:application/octet-stream;base64,eNcoDEdFiLEStuFf") to the desktop. I cannot provide a full URL to a server download due to security reasons (file needs to be handled clientside).
When I try what's given in the example of the blog post, a file which content and name is the current timestamp is created:
item.addEventListener("dragstart", function(evt) {
evt.dataTransfer.setData("DownloadURL", "data:application/octet-stream;base64,eNcoDEdFiLEStuFf");
}
I already tried changing the format parameter, tweaking the format of the data a little and deconding beforehand but nothing works, I never get any of my data onto my desktop. Is there any way to accomplish what I am looking for, at least in some browsers?
By the way, we do not use jQuery. As a result, it might be interesting if there is a solution with jQuery but this will most probably not be applicable for our project.
As far i understood download URL should have following format:
mime-type:file_name:URL. Were URL is your data URI.
For your case:
item.addEventListener("dragstart", function(evt) {
evt.dataTransfer.setData("DownloadURL", "application/octet-stream:fileName.bin:data:application/octet-stream;base64,eNcoDEdFiLEStuFf");
}
Which should create fileName.bin file.
Take a look at http://jsfiddle.net/Andrei_Yanovich/jqym7wdh/
But it looks like it works only in chrome

how to secure img src path when user clicks on view source using javascript?

How to secure the src path of the image when clicks on inspect element so that user should not get to know about the actual src path..please help me with the solution and it should be done with javascript only no other tags should be used.
You can convert image into base 64 data URIs for embedding images.
Use: http://websemantics.co.uk/online_tools/image_to_data_uri_convertor/
Code sample:
.sprite {
background-image:url(data:image/png;base64,iVBORw0KGgoAAAA... etc );
}
This is commonly done server-side, where you have an endpoint that serves the image file to you as bytes...
You can store the images in a private location on the server where IIS/<your favourite web server> doesn't have direct access to it, but only a web app, running on it, with the required privilege is authorized to do so.
Alternatively people also "store" the images in the database itself and load it directly from there.
In either case, the response which has to be sent back has to be a stream of bytes with the correct mime type.
Edit:
Here are a couple of links to get you started if you are into ASP.NET:
http://www.codeproject.com/Articles/34084/Generic-Image-Handler-Using-IHttpHandler
http://aspalliance.com/1322_Displaying_Images_in_ASPNET_Using_HttpHandlers.5 <- this sample actually does it from a database.
Don't let the choice of front-end framework (asp.net, php, django, etc) hinder you. Search for similar techniques in your framework of choice.
Edit:
Another way if you think html5 canvas is shown here: http://www.html5canvastutorials.com/tutorials/html5-canvas-images/
However you run into the same problem. Someone can view the image url if they can see the page source. You'll have to revert to the above approach eventually.

How to generate and prompt to save a file from content in the client browser? [duplicate]

This question already has answers here:
Create and save a file with JavaScript [duplicate]
(11 answers)
Closed 7 years ago.
I have a situation where I need to give my users the option to save some data stored locally in their client memory to disk. The current workaround I have is having a handler like this
(define-handler (download-deck) ((deck :json))
(setf (header-out :content-type) "application/json"
(header-out :content-disposition) "attachment")
deck)
which does exactly what it looks like. The client sends their data up, and saves the returned file locally.
This seems stupid.
Please, please tell me there's a better, simpler, cross-browser way to let a client save some local data to their disk with a file-save dialog box.
Every answer I read on the subject either says "no, you can't save files with javascript" or "yes, there's this one semi-documented piece of the Chrome API that might let you do it in three pages".
This "FileSaver" library may help. If you want it to be reasonably cross-browser, you'll also need this to implement the W3C Blob API in places it's not already implemented. Both respect namespaces, and are completely framework agnostic, so don't worry about naming issues.
Once you've got those included, and as long as you're only saving text files, you should be able to
var blob = new Blob(["Hello, world!"], {type: "text/plain;charset=utf-8"});
saveAs(blob, "hello world.txt");
Note that the first argument to new Blob has to be a list of strings, and that you're expected to specify the filename. As in, the user will see this file being downloaded locally, but won't be able to name it themselves. Hopefully they're using a browser that handles local filename collisions...
This is my code:
<a id='tfa_src_data'>Export</a>
document.getElementById('tfa_src_data').onclick = function() {
var csv = JSON.stringify(localStorage['savedCoords']);
var csvData = 'data:application/csv;charset=utf-8,'
+ encodeURIComponent(csv);
this.href = csvData;
this.target = '_blank';
this.download = 'filename.txt';
};
You can use various data types.
Depending on what you are trying to do exactly, the HTML5 local storage concept might help you.
So what is HTML5 Storage? Simply put, it’s a way for web pages to store named key/value pairs locally, within the client web browser. Like cookies, this data persists even after you navigate away from the web site, close your browser tab, exit your browser, or what have you. Unlike cookies, this data is never transmitted to the remote web server (unless you go out of your way to send it manually). http://diveintohtml5.info/storage.html
There's also the Filesystem API (so far only implemented in Chrome AFAIK)
http://www.html5rocks.com/en/tutorials/file/filesystem/

How best to export a grid to PDF in ASP.NET MVC

I don't know that this is necessarily important, but I'm using Infragistics iggrid for my grid and their Reports stuff to export to PDF.
The underlying issue I have is that my data that I want to export is in the browser and I would prefer that I don't have to create a server-side file to download. We have an icon on the screen that the user clicks to download the PDF.
So what I'm doing on the client, is collecting all the data. This has to be done client-side because I want to export the data as the user has it sorted, filtered, and column-ordered (otherwise I could just collect the data server-side which would make this simpler). I then send the data to the server via a POST.
On the server-side I generate the PDF file. Now, obviously, I could save the PDF server-side and redirect to the generated file, but that adds maintenance of temporary files which I'd prefer to avoid (but worst case, I can go there. Just fishing for options right now).
I tried returning the data base64 encoded and then doing:
window.open("data:application/pdf;base64," + encodedData);
This doesn't work (at least in IE) because the URL limit is a bit over 2K.
I tried using the downloadDataURI javascript function here: http://code.google.com/p/download-data-uri/
But that only appears to work with Chrome (even after commenting out the webkit check) and I'm apparently not clever enough to figure out why.
I'm sure I'm missing some obvious possibility that doesn't require creating a server-side file, but I'm just not seeing it. (disclaimer: My daughter woke me up horribly early this morning so the answer could be really trivial and I will feel stupid tomorrow when my brain is working).
On the server-side I generate the PDF file. Now, obviously, I could
save the PDF server-side and redirect to the generated file, but that
adds maintenance of temporary files which I'd prefer to avoid (but
worst case, I can go there. Just fishing for options right now).
You don't need to save it on the server. You can simply stream the PDF File (I assume you have it in some sort of Stream or byte[]) to the user. All you need to do is something like
Response.ContentType = "application/pdf";
Response.AddHeader("Content-Disposition", "filename.pdf");
Response.BinaryWrite(bytes);
Response.Flush();
Response.Close();
Response.End();
And this will prompt the user to either save the file or open it in Adobe Reader. The file won't be created on the server at all.

Categories