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.
Related
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
I am trying to build a local video player in nwjs (node-webkit). I was able to play the local files by adding their path as the video element's src attribute, but now I want to make use of MediaSource and ,probably necessary, URL.createObjectUrl().
The problem is I haven't found any documentation that allowed me to achieve this, during my tests I am unable to append a new source to MediaSource as the local file. I tried direct paths and XHR requests, the closest I have been was with the XHR request of the file but I cannot convert the xhr.response into a usable item for my purpose, such as a objecturl.
For some reason just changing the src attribute directly each time a new video is selected causes the memory usage to grow constantly, which is why I would like to try doing this via the MediaSource api.
Since there's a lack of such information I would appreciate if anyone could help.
I was able to discover how this could be done, first there needs to be a mediasource object with which you use URL.createObjectUrl to link to the video.src, and then you create a buffer on it. It is to that buffer that is appended the media which is loaded via XMLHttpRequest with the Content-type set as an arraybuffer.
Careful with big files, if you don't segment them and load everything at once it will eat your ram and even crash your application.
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.
I am trying to create a blob in Javascript to serve up a file. However, the link created by window.URL.createObjectURL(blob) becomes invalid over time. I wish to be able to generate a link that will be valid for as long as the page is open. Looking online, I saw that the autoRevoke option is set to true, so this led me to believe that the url is being revoked when not being used actively. I tried setting it to false, but I get a TypeError.
Here is the code:
var res = xhr.response;
var blob = new Blob([res]);
var url = window.URL.createObjectURL(blob, {autoRevoke : false});
Here is the error:
Uncaught TypeError: Type error background.js:52
How can I prevent the blob's url from becoming invalid?
If you save the blob to the file system using the API discussed here:
http://www.html5rocks.com/en/tutorials/file/filesystem/
You can create a file system URL that will persist. This solution does have the downside of a prompt to the user to approve saving files.
Can you talk more about the feature as the user would see it? What are you linking to?
In response to your comment:
I recommend keeping the input element in the DOM for as long as you want to hold a reference to the file's content. If you're linking to the content, you could create create a link that invokes a function with the input element's unique id. This function would generate a blob URL on demand and forward the browser to that URL. If you're using the URL as an img src or something similar, then perhaps your app has a user interaction that still allows for you to create the blob URL on demand.
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.