html5 fileapi binary data - html

Can you get the binary data from a file without the fileReader class? I'm trying to upload files and I have it working in firefox & chrome/webkit but safari 5 doesn't have filereader.
There has to be a way to get the binary data as gmail has drag and drop that works in safari 5.

I worked it out, thanks to the demo here: http://webreflection.blogspot.com/2009/03/safari-4-multiple-upload-with-progress.html
I just need to feed the dataTransfer File...
var file = e.dataTransfer.files[0];
var xhr = new XMLHttpRequest();
xhr.open("POST", "upload_process.php", true);
xhr.send(file); //passing in file object seems to work

I have been facing the same problem but i am still not sure about the xhr.send(file). As while using the ASP.NET i got the error "Potentially dangerous data is detected ... ". I thought xhr.send(file) is not implemented by Safari considering FireReader itself is missing.
Its nice to know that xhr.send(file) works in the Safari. I will try investigate it further.
However there is a better alternative for this which works great FormData.
var file = e.dataTransfer.files[0];
var xhr = new XMLHttpRequest();
xhr.open("POST", "upload_process.php", true);
var fd= new FormData(); //its supported in the safari, chrome and firefox 4
fd.append(file.name, file);
xhr.send(fd); //passing in file object seems to work
There is one more issue i am facing right now, its HTML5 DataTransfer detection error in Chrome please let me know in case you have faced and found any solution for this.

Related

Cannot refresh <object/> when changing from application/pdf to text/html

I am trying to refresh an element in the DOM tree. Basically the typescript code simply update the data & type of an existing HTMLObjectElement. Here is the pseudocode:
const textCanvas: HTMLObjectElement = <HTMLObjectElement>(curElement.children.namedItem('text-canvas'));
// Populate both the actual data as well as the associated mime/type:
textCanvas.data = enabledTextElement.textData; // 'blob:http://localhost:8081/d3c9a0ac-8e40-4e0e-aeb8-91656273837c'
textCanvas.type = enabledTextElement.mimeType; // 'application/pdf'
Which then gets updated with:
textCanvas.data = enabledTextElement.textData; // 'blob:http://localhost:8081/3c5ad888-0a7f-41d0-8ec9-35c334ef3f20'
textCanvas.type = enabledTextElement.mimeType; // 'text/html'
My chrome simply display the PDF version:
The funny part is if I do the opposite (html first), then the element gets properly updated (html text is displayed, then the PDF box is displayed). I tried to verify if this is supposed to work at:
https://html.spec.whatwg.org/multipage/iframe-embed-object.html#the-object-element
And it seems it should. I also found an old bug report:
https://bugs.chromium.org/p/chromium/issues/detail?id=123536
-> <object> works in every browser except Google Chrome
Using:
Google Chrome 80.0.3987.163 (Official Build) (64-bit) (cohort: 81_Win_122)
Revision e7fbe071abe9328cdce4ffedac9822435fbd3656-refs/branch-heads/3987#{#1037}
OS Windows 8.1 (Build 9600.19676)
JavaScript V8 8.0.426.30
If that help the URL are created from a Blob which is then passed to URL.createObjectURL.
I am currently using the following work-around:
textCanvas.data = '';
textCanvas.type = enabledTextElement.mimeType;
textCanvas.data = enabledTextElement.textData;
Seems to make the symptoms go away. I've filled a bug report just in case:
https://bugs.chromium.org/p/chromium/issues/detail?id=1076373

How to embed a Base64 encoded PDF data URI into a HTML 5 `<object>` data attribute?

So in my application, users have the option to upload a file to an <input type = "file" id = "my-file"> (HTML 5 File input). I can subsequently grab this file using the following Javascript:
var files = $("#my-file").files;
var file = files[0];
Can I somehow use this var file as the data in an <object> tag? Here is an example of an object tag where the PDF is grabbed by hitting a URL and contacting the server.
<object data="data/test.pdf" /*<-- I want the var file here */ type="application/pdf" width="300" height="200">
</object>
How can I accomplish this? Please note, I must support Internet Explorer 11.
UPDATE:
I've tried something that ultimately ended in failure. I converted the PDF to a data-uri using FileReader and then used that in the data attribute of the <object> tag, which renders perfectly in Chrome but not at all in Internet explorer.
var files = $(e.currentTarget.files);
file = files[0];
var reader = new FileReader();
reader.onloadend = function() {
var data = reader.result;
console.log(data);
$("#content").prepend('<object id="objPdf" data="'+data+'" type="application/pdf"></object>');
};
reader.readAsDataURL(file);
Where the reader data comes out looking like:
data:application/pdf;base64,JVBERi0xLjQKJe...
Here is the reason PDF's don't work with this approach in Internet Explorer (images only)...so sad :(
UPDATE 2:
Tried pdf.js with some success...it displays the PDF on the page, although it is incredibly slow (5 seconds for a single page) in Internet Explorer 11. It also only displays one page at a time, whereas the <object> tag displayed all pages instantly in a nice scrollable container. While this is an extreme fallback option, I'd like to not go down this route.
Anyone have any other idea as to how I can preview the PDF's that the user uploads directly in the webpage?
Yes I got it working with a file...
HTML:
<object id="pdf" data="" type="application/pdf"></object>
Javascript (Jquery)
var fr = new FileReader();
fr.onload = function(evtLoaded) {
$('#pdf').attr('data', evtLoaded.target.result );
};
fr.readAsDataURL(inFile);
Compared to your approach I use the 'I am done reading the file'-callback differently by using the event.
If I got it right: 'loadend' will always be called no matter if reading succeeded or failed.
Appendix on 04AUG2021:
#Adil talks about a plural of PDFs. Well, this solution talks about 1, I never tried several PDFs. Since the solution is made by an html 'id' we know that the 'id' comes with a singleton pattern per page. Nevertheless, I am convinced it is doable with severla PDFs per page somehow with whatever use case one creates.
#netotz I did not investigate here. It just comes to my mind that it could come to issues regarding the hardware. You do not mention the browser where it happens nor any operating system internals... I just guess (though I can be wrong) that 1.8 MB is rather a small amount of data...
In addition to the above answer and the comments from Dirk's answer.(Since I don't have 50 reputation to comment directly)
I want to point out that there is a way to prevent the issue that
<object> has an issue rendering base64 data directly when the file size is bigger than 1mb.
Steps:
Convert base64 to blob
Create URL from blob
use the URL as the data's src
A good post can be found here: an answer for another pdf lib. But this also suitable for our case.

First Chrome Extension

I have a page one my website that I'd like to emulate into a 'newtab' chrome extension.
I want to make something similar to this:
https://chrome.google.com/webstore/detail/animatedtabs-a-new-gif-on/kenhfdoiondldpcoajdbackbnmehgahl?hl=en
I have a lot of information on my server that i'd like to be able to serve as a chrome newtab extension - and this extension above loads a different GIF everytime a new tab is opened - how do they get data from their server? I don't seem to be able to find a way to do this.
I found the answer, for anyone wondering. The answer came in the form of this page:
https://developer.chrome.com/extensions/xhr
Which basically states that if you put a URL into the 'permissions' field in the manifest.json file, you can then access that URL in your application using the JS found on that page, eg:
var xhr = new XMLHttpRequest();
xhr.open("GET", "http://api.example.com/data.json", true);
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
// innerText does not let the attacker inject HTML elements.
document.getElementById("resp").innerText = xhr.responseText;
}
}
xhr.send();
I've now got my chrome extension working perfectly!

Opening a local XML file in Google Chrome

Our tool will look like below
Input an XML file.
Click Load button will do transformation of the XML file and display it in a table format.
Currently the tool is working fine in IE and Firefox. Now we have the requirement to support it for Chrome also.
Inside html file JavaScript, we are doing the XML transformation using the XSLT file. For the purpose of loading XML we are creating a DOM object for different browsers as below.
if(window.ActiveXObject) {
XMLObject = new ActiveXObject('Microsoft.FreeThreadedXMLDOM');
}
else {
XMLObject = document.implementation.createDocument("", "", null);
}
But for Chrome we are not able to find the Compatible DOM object code. While searching in web found that the below code will work in Chrome.
XMLObject =new XMLHttpRequest();
Tried with the above method , but it is throwing the error “Cross origin requests are only supported for HTTP”.
Also while loading XML file found that the browser is not giving the correct path of the filename, instead its giving like C:\fakepath\Sample.xml.
Any other way to solve this issue?
If you want to use XMLHttpRequest to access files from the local file system then you have to start Chrome with the command line option --allow-file-access-from-files.

Force download in Google Chrome Extension

I'm writing an Google Chrome extension that lets you download a backup file of your data. I want the user to be able to press a button and a "Save as" dialog box should open and they can save the file to their computer. Nothing appears to work and I have not found an answer on the internet. I have tried several approaches:
Using document.execCommand('SaveAs', null, 'filename.json'); This does not work because this command is IE-only and there does not appear to be a Webkit-alternative
Using data URIs. This was the most promising and worked in Opera and Firefox, but the problem being that neither Chrome nor Safari appear to support the Content-disposition=attachment;-header in the URI. This should work. (Chrome doesn't even allow me to ctrl/cmd+s a page from a data URI)
Using an XMLHTTPRequest. I haven't tried this, but there has to be some way in which you could relay the request around? Please note that I do not want to use an external server (in that case I could have simply sent a POST-request and applied a Content-disposition:-header)
Using an available Chrome Extension API. But there does not seem to be anything for this purpose.
The reason I don't want to use any external server is that I don't want to have to pay for the hosting, and the data sent might be sensitive to the user, and I don't want infringe on anyone's privacy.
Has anyone gotten this to work?
I did it as follows in Appmator code on Github.
The basic approach is to build your Blob, however you want (Chrome/WebKit/Firefox has a responseBlob on XmlHttpRequest so you can use that), create an iframe (hidden, display:none) then assign the src of the iframe to be the Blob.
This will initiate a download and save it to the filesystem. The only problem is, you can't set the filename yet.
var savaeas = document.getElementById("saveas");
var bb = new (window.BlobBuilder || window.WebKitBlobBuilder)();
var output = Builder.output({"binary":true});
var ui8a = new Uint8Array(output.length);
for(var i = 0; i< output.length; i++) {
ui8a[i] = output.charCodeAt(i);
}
bb.append(ui8a.buffer);
var blob = bb.getBlob("application/octet-stream");
var saveas = document.createElement("iframe");
saveas.style.display = "none";
if(!!window.createObjectURL == false) {
saveas.src = window.webkitURL.createObjectURL(blob);
}
else {
saveas.src = window.createObjectURL(blob);
}
document.body.appendChild(saveas);