function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
sukanta Anbu 7sukanta Anbu 7 

The encoded multi-part file that I am sending through POST method is corrupted. I want to send a proper file

I am getting a file from lightning cmponent.I am using base64 in objreader in my helper.js to pass the file to the cntroller. I am doing a base64 encoding for multi-part file and the final body, I am doing a base64 decoding. However, this file is getting encoded 2 times cause of the encoding in js. Help me in decoding the file from js so I can do the encoding for multi-part.
The following is my helper.js file:

({
    MAX_FILE_SIZE: 4500000, //Max file size 4.5 MB 
    CHUNK_SIZE: 750000,      //Chunk Max size 750Kb 
     
    uploadHelper: function(component, event) {
        // get the selected files using aura:id [return array of files]
        var fileInput = component.find("fuploader").get("v.files");
        // get the first file using array index[0]  
        var file = fileInput[0];
        var self = this;
        // check the selected file size, if select file size greter then MAX_FILE_SIZE,
        // then show a alert msg to user,hide the loading spinner and return from function  
        if (file.size > self.MAX_FILE_SIZE) {
            component.set("v.fileName", 'Alert : File size cannot exceed ' + self.MAX_FILE_SIZE + ' bytes.\n' + ' Selected file size: ' + file.size);
            return;
        }
         
        // create a FileReader object 
        var objFileReader = new FileReader();
        // set onload function of FileReader object   
        objFileReader.onload = $A.getCallback(function() {
            var fileContent = objFileReader.result;
            var base64 = 'base64,';
            var dataStart = fileContent.indexOf(base64) + base64.length;
             
            fileContent = fileContent.substring(dataStart);
            // call the uploadProcess method 
            self.uploadProcess(component, file, fileContent);
        });
         
        objFileReader.readAsDataURL(file);
    },
     
    uploadProcess: function(component, file, fileContent) {
        // set a default size or startpostiton as 0 
        var startPosition = 0;
        // calculate the end size or endPostion using Math.min() function which is return the min. value   
        var endPosition = Math.min(fileContent.length, startPosition + this.CHUNK_SIZE);
         
        // start with the initial chunk, and set the attachId(last parameter)is null in begin
        this.uploadInChunk(component, file, fileContent, startPosition, endPosition, '');
    },
     
     
    uploadInChunk: function(component, file, fileContent, startPosition, endPosition, attachId) {
        // call the apex method 'SaveFile'
        var getchunk = fileContent.substring(startPosition, endPosition);
        var action = component.get("c.SaveFile");
        action.setParams({
            recordId: component.get("v.recordId"),
            fileName: file.name,
            contentType: file.type,
            file: fileContent
            
        });
         
        // set call back 
        action.setCallback(this, function(response) {
            // store the response / Attachment Id   
            returnValue = response.getReturnValue();
            var state = response.getState();
            if (state === "SUCCESS") {
                // update the start position with end postion
                startPosition = endPosition;
                endPosition = Math.min(fileContent.length, startPosition + this.CHUNK_SIZE);
                // check if the start postion is still less then end postion 
                // then call again 'uploadInChunk' method , 
                // else, diaply alert msg and hide the loading spinner
                if (startPosition < endPosition) {
                    this.uploadInChunk(component, file, fileContent, startPosition, endPosition, returnValue);
                } else {
                    alert('File has been uploaded successfully');
                }
                // handel the response errors        
            } else if (state === "INCOMPLETE") {
                alert("From server: " + response.getReturnValue());
            } else if (state === "ERROR") {
                var errors = response.getError();
                if (errors) {
                    if (errors[0] && errors[0].message) {
                        console.log("Error message: " + errors[0].message);
                    }
                } else {
                    console.log("Unknown error");
                }
            }
        });
        // enqueue the action
        $A.enqueueAction(action);
    },
})


The following is my apex class:

public class FileUploadController {
 
    @AuraEnabled
    public static String SaveFile(String recordId, String fileName, Blob file) {
         system.debug(recordId);
        system.debug(fileName);
        Http h = new Http();
//it should automaticaly catch the file name 
     //   String fileName = 'sf.pdf';
        String url = 'https://intelligent-sfdms.herokuapp.com/salesforce/jsonupload/'+ recordId+'/';
        String separationString = '2a8b828b-ee1e-461b-87fe-ce69c0491b04';
        String token = 'RGLYisTnzvEIRTCOJV7G3KUgnwNhYZXgKJJaOMQkgTq97RnDz6pmwuMqd9F9GBXy';
        
        String header = '--'+separationString+'\r\nContent-Disposition: form-data; name="file"; filename="'+ fileName +'" \r\nContent-Type: application/octet-stream';
      
      String footer = '--'+separationString+'--';             
      String headerEncoded = EncodingUtil.base64Encode(Blob.valueOf(header+'\r\n\r\n'));
      while(headerEncoded.endsWith('='))
      {
       header+=' ';
       headerEncoded = EncodingUtil.base64Encode(Blob.valueOf(header+'\r\n\r\n'));
      }
      String bodyEncoded = EncodingUtil.base64Encode(file);

      Blob bodyBlob = null;
      String last4Bytes = bodyEncoded.substring(bodyEncoded.length()-4,bodyEncoded.length());

        if(last4Bytes.endsWith('==')) {
        
        last4Bytes = last4Bytes.substring(0,2) + '0K';
        bodyEncoded = bodyEncoded.substring(0,bodyEncoded.length()-4) + last4Bytes;
        
        String footerEncoded = EncodingUtil.base64Encode(Blob.valueOf(footer));
        bodyBlob = EncodingUtil.base64Decode(headerEncoded+bodyEncoded+footerEncoded);
      } else if(last4Bytes.endsWith('=')) {
      
        last4Bytes = last4Bytes.substring(0,3) + 'N';
        bodyEncoded = bodyEncoded.substring(0,bodyEncoded.length()-4) + last4Bytes;
       
        footer = '\n' + footer;
        String footerEncoded = EncodingUtil.base64Encode(Blob.valueOf(footer));
        bodyBlob = EncodingUtil.base64Decode(headerEncoded+bodyEncoded+footerEncoded);              
      } else {
        // Prepend the CR LF to the footer
        footer = '\r\n' + footer;
        String footerEncoded = EncodingUtil.base64Encode(Blob.valueOf(footer));
        bodyBlob = EncodingUtil.base64Decode(headerEncoded+bodyEncoded+footerEncoded);  
      }

        system.debug('string ==>'+bodyBlob);
        system.debug('bodyBlob: ' + bodyBlob);


        HttpRequest req = new HttpRequest();
        req.setHeader('Content-Type', 'multipart/form-data; boundary=' +separationString);
        req.setHeader('X-CSRFToken', token);
        req.setHeader('Cookie', 'sessionid=ml0as2d28qbh8du2p3299ty2oof4axcu; csrftoken=RGLYisTnzvEIRTCOJV7G3KUgnwNhYZXgKJJaOMQkgTq97RnDz6pmwuMqd9F9GBXy');
        req.setHeader('Referer', 'https://intelligent-sfdms.herokuapp.com/salesforce/login/');
        req.setHeader('recordId', recordId);
        req.setEndpoint(url);
        req.setMethod('POST');
        req.setBodyAsBlob(bodyBlob);
        req.setTimeout(120000);
        system.debug('REQUEST: ' + req);

        // Send the request, and return a response
        HttpResponse res = h.send(req);
        System.debug(res.getBody());
        return res.getBody();
    }
}


Around line 12 or 13, I have to decode the blop file that I am getting through the paraeter from UI. Please help me decoding it.
If I convert the blob file to string and then decode it, I am able to decoe it. How ever the final blob fle can only be .csv or .txt. It is not accepting any other file types like png or pdf or jpg.So I cannot convert it to string. 

 How can I decode the file from the js file so I can use the Multi-part encoding that I have did?
Best Answer chosen by sukanta Anbu 7
sukanta Anbu 7sukanta Anbu 7
The base64 decoding was done on the end point url side. Once the decoding was done on the end point side, the situation was solved.