How to download a blob data as file in SAPUI5? - javascript

Dear SAPUI5 developers,
How can I download a blob data as file in SAPUI5?
I have a blob object:
"data:image/jpeg;base64,MjU1MjE2MjU1MjI0MDE2NzQ3MDc....."
I can not use the normal method that we usually use in JavaScript.
I mean window.URL.createObjectURL(blob); does not make a correct url for the blob data.
Can you tell me how can I do that?
Thanks in advance.

I had the same problem. Mostly you used sap.m.Link for creating the download link. I know if you create a anchor (a tag in HTML) and want to inject it in the body element you will receive the following warning:
ESLint(sap-no-dom-insertion): Direct DOM insertion is forbidden!
But ignore the warning and create a a tag and inject it in the body.
There is a good solution here:
JavaScript blob filename without link

You can create download link with object onfly and fire click event or user can click. Example: Create a file in memory for user to download, not through server

Related

refresh iframe after downloading a blob

I have a filebrowser on my server that uses Azure storage to store the files. The website has a feature where when you click on a file, it'll bring up a details window. I use ViewerJS to display a pdf preview of the file (if applicable), and it all works pretty well. The only problem is that when downloading the preview file, you have to reload the preview iframe manually to get it to display. The relevant php function is:
http://pastebin.com/sAyhsbfi
When this function is completed (I'm using ajax), the $.done function calls
response = JSON && JSON.parse(response) || jQuery.parseJSON(response);
$scope.pdfthingy=response; document.getElementById("viewerjs_preview").contentDocument.location.reload(true);
where response on the first line is set to the full pathname to the pdf preview file, and viewerjs_preview is the id of the relevant iframe.
For some reason, this isn't working, and the iframe isn't reloading itself. How do I make it do that when the blob has finished downloading, and pdfthingy is set?
Is the iframe’s domain the same as your host website’s domain? If not, we cannot access its contentDocument (or contentWindow) in host website’s JavaScript code.
To refresh the iframe, per my understanding you can set its src:
document.getElementById('viewerjs_preview').src = document.getElementById('viewerjs_preview').src;
Please note if the src contains a hash tag, we may need additional work. I’d like to suggest you to check What's the best way to reload / refresh an iframe using JavaScript? for more information.
Base on my experience, It is possible that we changed the IFrame URL, but the IFrame showed the preview contents. In this scenario, I suggest you can create the IFarme dynamic. For example, When you got the Blob URI form Azure storage, You could try to remove the Iframe and create a new. For instance, if Your preview content is shown in the iframe as :
<iframe id="viewerjs_preview" src = "/ViewerJS/#../azure blob storage url /pre-blobname .pdf " width='400' height='300' allowfullscreen webkitallowfullscreen></iframe>
You can try to use this code:
function recreateIFM() {
document.getElementById("viewerjs_preview").parentNode.removeChild(document.getElementById("viewerjs_preview"));
var ifm = document.createElement("iframe");
ifm.id = "viewerjs_preview";
ifm.width = "600px";
ifm.height = "400px";
ifm.src = "/ViewerJS/#../azure blob storage url /new-blobname .pdf";
document.body.appendChild(ifm);
}
Also, you can try MingXu's reference about how to refresh/reload the Iframe.
Regards,
Bill_Sww
I find the answer, the major reason is that we shouldn't use controllers to manipulate DOM.
sentence like document.getElementById("viewerjs_preview").contentDocument.location.reload(true) will not work anymore in angular scope, so you have to a directive to do it. I think the same question with you is and which's answer with most votes dose work well.
I think maybe my question was unclear, and for that I apologize. I'll try to go back and edit it tomorrow.
The solution for me was to, rather than set the src attribute of the iframe using angularjs, directly set it with
document.getElementById("iframe-id").src=/path_where_I_put_the_files/filename
(for reference I use "pdfthingy" to store the filename returned by the ajax call that downloads a blob).
This prevented the iframe from loading a null source before the filename was set.
This is perhaps part of why walkformusle has said that DOM should not be controlled in this manner.

testing blob urls

I'm using the Window.URL.createObjectURL function to generate a blob url for a local video file, which I then use to set the source of a <video> element. This loads the video when the URL is first constructed, and everything works well. But when the web page is reloaded, the generated URL is no longer valid -- the browser automatically revokes the generated URL.
My question: Is there a way to determine if this Blob URL has actually been revoked? In other words, how do I determine if I can still use this Blob url using javascript, jquery, or whatever options are out there?
I came up with a simple solution, which works... albeit, probably isn't ideal.
Basically, I take the url, set the <video> src to that url, and then attach a jquery error event handler to it. If the error event is called (which it is, if the blob url has been revoked) I then prompt the user to reselect their video file.

How to load images from the local machine to JS object avoiding loading to the server

I want to load an image file from the computer directly to any js object without using any server-side component. For example, I want to select a picture from the local machine and display it on a webpage. Is there a way to avoid file upload to the server?
In fact I want to write a kind of multiple image loader, but before loading to the server I want to rotate some images, create an xml-file with some data like user id, image file names list and to zip all images and this xml and then send it to the server. How can I do that on the client side?
There is a way with HTML5, but it requires the user to have dropped the file into a drop target or used a <input type="file"/> box, since otherwise it would be a security issue.
Using the File API you can read files, and specifically you can use the FileReader.readAsDataURL method to set the content as a data: URL for the image tag.
Here's an example:
$('#f').on('change', function(ev) {
var f = ev.target.files[0];
var fr = new FileReader();
fr.onload = function(ev2) {
console.dir(ev2);
$('#i').attr('src', ev2.target.result);
};
fr.readAsDataURL(f);
});​
http://jsfiddle.net/alnitak/Qszjg/
Using the new File APIs, it is possible to access content from the local disk.
You put a traditional <input type="file"> upload field on your page, and handle the onchange event.
MDN has a good writeup with all of the details.
Your event handler gets a FileList containing Files. From there, you can call FileReader.readAsDataURL(File) to fetch the content of the image and then pass that data URL to an <img> or a <canvas> to do rotation.
You can use createObjectURL method of the window.URL object, this doesn't have much browser support though
http://jsfiddle.net/LvAqp/ only works in chrome and firefox

Is there a way to let a user view an image they are about to upload client side before uploading to the server?

When a user is uploading an image, is there a way I can load the image client side and show it to them first, before uploading it to the server? Preferably using javascript/jquery only, but using flash would be acceptable too.
It is possible with the new FileReader interface defined in HTML5 and works on Firefox currently.
A file input has an associated files property which tracks the list of files currently selected for that input. To display a file from this list, create a new FileReader object, initialize its onload event handler, and read the file as a data URL.
// get the first file, foo is a file input field
var file = document.getElementById('foo').files[0];
// setup the reader and the load complete callback
var reader = new FileReader();
reader.onload = function(e) {
var image = new Image();
// string representing the image
image.src = e.target.result;
document.body.appendChild(image);
};
// read the file as a data url
reader.readAsDataURL(file);
Once the file is loaded, you will have access to its contents in a data url scheme, for instance:
data:image/jpeg;base64,...aqHI7sNyPGFjdtQvFr/2Q==
Create a new Image and set its src attribute to this data string.
See a working example here. Firefox only.
You can't really do this cross-browser in JavaScript alone due security restrictions that are in place, there are a few flash versions available though, here's one example (the free version does what you're after).
There are probably more free flash versions out there as well.
Since HTML 5 those things are possible, thanks to the File Object, File Reader and the ´files´ property of the input element.
See here for more information: http://demos.hacks.mozilla.org/openweb/ & http://hacks.mozilla.org/2009/12/file-drag-and-drop-in-firefox-3-6/.
Example (only for demonstration, requires FF 3.5+):
See here: http://gist.github.com/536024
In case you wonder, File.url is brand new, with it you dont anymore need to read the whole file into the memory, and assign the whole DataUrl (data:image/src,base64;DF15EDFE86..) to the src property.
Well, the <img> tag needs a path to the image. That path can be to something on the web, or to a local file. So far, so good. The trick is, how do you tell your javascript the path on the local system, so it can set the IMG SRC attribute.
The path of the file <input> tag is unavailable to javascript (as a security precaution --- you don't want a want page upload files from you system behind your back).
On the other hand, if you can get your users to enter a correct file path name into a text <input> field, then it should be possible.

Follow a URL using JavaScript

Is there any way to follow a URL in JavaScript without setting the document.location.href?
I have a page that displays a list of objects and each object may have a file download associated with it, which is accessed via a hyperlink. Clicking the link initiates an AJAX request that ultimately leads to a transient file being generated that can be referenced by a unique and temporary URL.
At the moment when the AJAX call completes, it simply sets the document.location.href to the temporary URL and the file download is initiated. Of course this has the side effect of changing the URL in the browser's address bar, so if the page is refreshed the file is downloaded again rather than the object listing page itself getting refreshed. I guess I could set the URL back to what it was before, but that feels a bit hacky.
Incidentally, I'm using the Prototype JavaScript framework.
you could open a new window with the new url? or try setting an iframe's url to the new url, both should present a file download (the latter being the better option)
You could use a hidden iframe - set the src of that to the file to download.
If you're doing all this just to trigger a file download, it sounds like a good application for using a hidden Iframe. Set the SRC of the Iframe instead, so you don't have to mess with the main page.

Categories