I have the constraint of sending data to a server in JSON format only, and I need to send a PDF file together with other form data in the JSON. I though I could make a string from it with base64 like in this solution I found on SO:
let data = {foo: 1, bar: 2};let reader = new FileReader();reader.readAsDataURL(pdf);reader.onload = () => { data.file = reader.result; $.ajax({type: 'POST', dataType: "json", data: JSON.stringify(data), ...});}
But it happened that reader.result
does not contain the whole PDF (whether I save it to file instead of sending, or get it back from the server). In a text editor the content is the same, but a binary editor says that some bytes are missing. My browser can load it as a pdf and the title shows, but the page is blank.
I also tried reader.readAsBinaryString
and transform to base64 myself with btoa
, but same result.
Edit: CodePen example: https://codepen.io/jdelafon/pen/eRWLdz?editors=1011
Edit: to verify, I did this:
let reader = new FileReader();reader.readAsBinaryString(pdf);reader.onload = () => { let blob = reader.result; let file = new Blob([blob], {type: 'application/pdf'}); let fileURL = window.URL.createObjectURL(file); // make it display in <embed>};
The body of the pdf is empty. If I replace file
by the original pdf
, it gets displayed entirely. So FileReader loses data in the process.
Image may be NSFW.
Clik here to view.
Is there a better way? Is it an encoding issue with FileReader
?
I also though about using FormData like this:
let data = {foo: 1, bar: 2};let fd = new FormData();fd.append('file', pdf);data.file = btoa(fd);$.ajax({type: 'POST', dataType: "json", data: JSON.stringify(data), ...});
But now when I fetch the data back from the server, JS has no idea that it represents a FormData object, so I don't know how to get the file back for display in a browser. Is it possible?