How to load a PDF into a blob so it can be uploaded?

RutledgePaulV picture RutledgePaulV · Sep 9, 2014 · Viewed 9.9k times · Source

I'm working on a testing framework that needs to pass files to the drop listener of a PLUpload instance. I need to create blob objects to pass inside a Data Transfer Object of the sort generated on a Drag / Drop event. I have it working fine for text files and image files. I would like to add support for PDF's, but it seems that I can't get the encoding right after retrieving the response. The response is coming back as text because I'm using Sahi to retrieve it in order to avoid Cross-Domain issues.

In short: the string I'm receiving is UTF-8 encoded and therefore the content looks like you opened a PDF with a text editor. I am wondering how to convert this back into the necessary format to create a blob, so that after the document gets uploaded everything looks okay.

What steps do I need to go through to convert the UTF-8 string into the proper blob object? (Yes, I am aware I could submit an XHR request and change the responseType property and (maybe) get closer, however due to complications with the way Sahi operates I'm not going to explain here why I would prefer not to go this route).

Also, I'm not familiar enough but I have a hunch maybe I lose data by retrieving it as a string? If that's the case I'll find another approach.

The existing code and the most recent approach I have tried is here:

    var data = '%PDF-1.7%����115 0 obj<</Linearized 1/L ...'
    var arr = [];
    var utf8 = unescape(encodeURIComponent(data));
    for (var i = 0; i < utf8.length; i++) {
        arr.push(utf8.charCodeAt(i));
    }

    var file = new Blob(arr, {type: 'application/pdf'});

Answer

shanabus picture shanabus · Aug 19, 2017

It looks like you were close. I just did this for a site which needed to read a PDF from another website and drop it into a fileuploader plugin. Here is what worked for me:

    var url = "http://some-websites.com/Pdf/";

    //You may not need this part if you have the PDF data locally already
    var xhr = new XMLHttpRequest();
    xhr.onreadystatechange = function () {
        if (this.readyState == 4 && this.status == 200) {
            //console.log(this.response, typeof this.response);
            //now convert your Blob from the response into a File and give it a name
            var fileOfBlob = new File([this.response], 'your_file.pdf');

            // Now do something with the File
            // for filuploader (blueimp), just use the add method
            $('#fileupload').fileupload('add', {
                files: [ fileOfBlob ], 
                fileInput: $(this)
            });
        }
    }
    xhr.open('GET', url);
    xhr.responseType = 'blob';
    xhr.send();  

I found help on the XHR as blob here. Then this SO answer helped me with naming the File. You might be able to use the Blob by itself, but you won't be able to give it a name unless its passed into a File.