1

I tried to convert a base64 string generated from pdf file using FileReader.readAsDataURL() to its original format.
In NodeJS I did it like this and it was able generated the pdf to its initial state.

filebuffer = "data:application/pdf;base64,JVBERi0xLjQKJSDi48/..........."
let base64file = fileBuffer.split(';base64,').pop();
fs.writeFileSync('download.pdf',base64file,{encoding:'base64'},function(err){
    if(err === null){
        console.log("file created");
        return;
    }
    else{
        console.log(err);
        return;
    }
})

But i tried to do it in HTML + Javascript in this way.But in this way , pdf was empty/no letter wasn't in it

let stringval = "data:application/pdf;base64,JVBERi0xLjQKJSDi48/..........."
let encodedString = stringval.split(';base64,').pop();

let data = atob(encodedString);
let blob = new Blob([data]);

// //if you need a literal File object
let file = new File([blob], "filename");

link.href = URL.createObjectURL(file);
link.download = 'filename';

I was Capturing file and converting to base64 string in this way:

captureFile: function () {
event.preventDefault();
const file = event.target.files[0];
$("#labelinput1").html(file.name);
const reader = new window.FileReader();
reader.readAsDataURL(file);
reader.onloadend = () => {
  var x = reader.result.toString();
  App.buffer2 = x;
  console.log("buffer", App.buffer);
};}

Then after clicking a button , I added the buffer to IPFS node

addfile: async function () {
if (App.buffer2 === null) return;
App.node = await window.Ipfs.create()
App.node.add(App.buffer2, function (errx, resipfs) {
      if (errx === null) {
        console.log(resipfs[0].hash);
        App.buffer2 = null;
        return App.showInfo(resipfs[0].hash);
      }
      else {
        return App.showError(errx.message.toString() + errx.stack.toString());
      }
    });
}

using the IPFS HASH i can get back the base64 encoded string , I retrieved this string in this way:

ipfsfiledownload: async function () {
var filebuffer = await App.node.cat(hashtext);
var stringval = filebuffer.toString();
//convert this string to main file
}

I used Truffle Petshop and write those functions in top of it. Here is a IPFS hash QmfSefUiwjV44hpfnHyUngGATyHm9M4vN3PzF1mpe59Nn1. you can try out this Hash value in nodejs with this code

const IPFS = require('ipfs');
const fs = require('fs');
const main = async() => {
    const node = await IPFS.create()
    var fileBuffer = await 
    node.cat('QmfSefUiwjV44hpfnHyUngGATyHm9M4vN3PzF1mpe59Nn1')
    fileBuffer = fileBuffer.toString()
    let base64file = fileBuffer.split(';base64,').pop();
    fs.writeFileSync('download.pdf',base64file, {encoding:'base64'},function(err){
        if(err === null){
            console.log("file created");
            return;
        }
        else{
            console.log(err);
            return;
        }
    })
}

main()

You can find the full code here. What I am doing wrong and how to solve it?

5
  • Is stringval a hard coded string or are you getting it from the filereader calls? If it is the latter you need to do all that in the filereader onload or onloadend event. Also you can use the blob instead of file here, eg URL.createObjectURL(blob). Show a minimal reproducible example so we can properly see what is going on Commented Nov 30, 2019 at 1:52
  • I think writing to file with base64 encoding is actualy the opposite of calling atob function Commented Nov 30, 2019 at 2:46
  • It is the latter, from filereader calls. After I got the base64 String i uploaded it to IPFS Files(ipfs.io). Using IPFS hash i can get back the base64 string . I was trying to convert it to the same file Commented Nov 30, 2019 at 7:21
  • I think I added the most of the procedure I done and also added a nodejs code to I used to test the IPFS hash and differentiate the result. Should I detail my code more ..? @PatrickEvans Commented Nov 30, 2019 at 8:00
  • wouldn't this work Buffer.from("base64string", "base64").toString("utf8"); Commented Nov 30, 2019 at 15:30

1 Answer 1

2

After converting the base64 string using atob() , I converted it to Uint8Array Then created the blob and file . It seems to work now ..

Here is the full code :

ipfsfiledownload: async function () {
    var hashtext = document.getElementById("id_ipfshash").value //getting the IPFS HASH
    var link = document.getElementById("downloadLink"); 
    if (hashtext === null) return
    var filebuffer = await App.node.cat(hashtext); //getting the base64 string from IPFS
    var stringval = filebuffer.toString();

    console.log(stringval);
    let encodedString = stringval.split(',')[1]; //getting the base64 hash
    let mimetype = stringval.split(',')[0].split(':')[1].split(';')[0]; //getting the mime type

    let data = atob(encodedString); //ascii to binary
    var ab = new ArrayBuffer(data.length); 
    var ia = new Uint8Array(ab);
    //converting to Uint8Array
    for(var i = 0;i<data.length;i++){
          ia[i] = data.charCodeAt(i);
    }
    let blob = new Blob([ia],{ "type": mimetype});
    let filename = 'filename.' + App.getExtension(mimetype);
    let file = new File([blob], filename);

    link.href = window.URL.createObjectURL(file);
    link.download = filename;
    link.click();
}
Sign up to request clarification or add additional context in comments.

2 Comments

do u compared the Checksums? i tested something with offers downlods over JS and my generated files from js where different to the orginal files i encoded with php. My steps: orginal file => base64 with php => send the string over ajax to js, decoded with js
I checked with sha256 and they matched

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.