Проведя так много дней, я смог разобраться в проблеме. Это было с длиной файла.
Ниже приводится полная рабочая реализация «Загрузить в Azure Blob с Salesforce APEX»
Компонент молнии
<aura:component controller="FileUploadController" implements="flexipage:availableForAllPageTypes,flexipage:availableForRecordHome,force:hasRecordId,force:lightningQuickAction" access="global" >
<aura:attribute name="azureservice" type="Object" />
<aura:attribute name="accept" type="List" default="['.jpg', '.jpeg', '.pdf', '.Docx', '.Doc']"/>
<aura:attribute name="multiselect" type="Boolean" default="true"/>
<aura:attribute name="disabled" type="Boolean" default="false"/>
<aura:attribute name="fileName" type="String" default="No File Selected.." />
<lightning:card variant="Narrow" title="File Upload">
<!-- Lightning Input with file type and on file change call the 'handleFilesChange' controller -->
<div style="padding 10px">
<lightning:input aura:id="fileId" onchange="{!c.handleFiles}" type="file" name="file" label="Upload File" multiple="true"/>
<div class="slds-text-body_small slds-text-color_error">{!v.fileName} </div>
<br/>
<div class="slds-is-relative">
<lightning:spinner aura:id="Spinner" alternativeText="Loading..." size="small" class="slds-hide"/>
</div>
</div>
<lightning:buttonGroup>
<div class="slds-m-top_medium">
<lightning:button label="Cancel" onclick="{!c.handleCancel}" class="slds-m-top--medium"/>
</div>
<div class="slds-m-top_medium">
<lightning:button label="Save" onclick="{!c.handleUpload}" class="slds-m-top--medium" />
</div>
</lightning:buttonGroup>
</lightning:card>
</aura:component>
FileUploadController Javascript
({
handleFiles: function(component, event, helper) {
var fileName = 'No File Selected..';
if (event.getSource().get("v.files").length > 0) {
console.log('fileName--->'+fileName)
fileName = event.getSource().get("v.files")[0]['name'];
}
component.set("v.fileName", fileName);
},
handleUpload: function(component, event, helper) {
if (component.find("fileId").get("v.files").length > 0) {
console.log('No of files-->'+component.find("fileId").get("v.files").length);
//Calling helper method to upload the file
//Show Spinner while request is in process
helper.showSpinner(component);
helper.uploadHelper(component, event);
helper.hideSpinner(component);
} else {
alert('Please Select a Valid File');
}
}
})
Помощник Javascript
({
uploadHelper: function(component, event) {
// start/show the loading spinner
component.set("v.showLoadingSpinner", true);
// get the selected files using aura:id [return array of files]
var fileInput = component.find("fileId").get("v.files");
// get the first file using array index[0]
var file = fileInput[0];
var fileType = file.type;
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.showLoadingSpinner", false);
component.set("v.fileName", 'Alert : File size cannot exceed ' + self.MAX_FILE_SIZE + ' bytes.\n' + ' Selected file size: ' + file.size);
return;
}
var objFileReader = new FileReader();
objFileReader.onload = $A.getCallback(function() {
var fileContents = objFileReader.result;
var base64 = 'base64,';
var dataStart = fileContents.indexOf(base64) + base64.length;
fileContents = fileContents.substring(dataStart);
// call the uploadProcess method
self.uploadProcess(component, file, fileContents);
});
objFileReader.readAsDataURL(file);
},
uploadProcess: function(component, file, fileContents) {
var action = component.get("c.upload");
action.setParams({
base64Data: fileContents,
filelength: file.size,
fileType: file.type,
fileName: file.name
});
// set call back
action.setCallback(this, function(response) {
var isUploaded = response.getReturnValue();
if(isUploaded==true)
{
var state = response.getState();
if (state === "SUCCESS") {
console.log('your File is 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");
}
}
console.log('Your File is uploaded successfully');
}else{
console.log("Your File is has not uploaded successfully");
}
});
$A.enqueueAction(action);
},
showSpinner:function(component){
var spinnerMain = component.find("Spinner");
$A.util.removeClass(spinnerMain, "slds-hide");
},
hideSpinner:function(component){
var spinnerMain = component.find("Spinner");
$A.util.addClass(spinnerMain, "slds-hide");
}
})
FileUploadController
public class FileUploadController {
@AuraEnabled
public static Boolean upload(String base64Data, Integer filelength, String fileType, String fileName ){
Blob blobData = EncodingUtil.base64Decode(base64Data);
AzureService service = new AzureService();
Boolean isUploaded = service.uploadBlob(blobData, filelength, fileType, fileName);
// AzureService.generateAuthorizationHeader(blobData, filelength, fileType);
return isUploaded;
}
}
AzureService
public class AzureService {
private String storageKey;
private String storageName;
private String storageContainer;
private String storageUrl;
private String blobName;
private String requestURL;
private String fileLength;
private String formattedDate ;
private String fileType;
private String fileName;
private final string DATEFORMAT = 'EEE, dd MMM yyyy HH:mm:ss z';
private final string VERSION = '2015-12-11';
private final string BLOB_TYPE = 'BlockBlob';
public Boolean uploadBlob( Blob fileBody, Integer intFileLength, String strFileType, String strFileName)
{
Boolean isUploaded= false;
this.fileName = EncodingUtil.urlEncode(strFileName, 'UTF-8');
this.fileType = strFileType;
this.storageName = 'YourStorageName';
this.storageContainer = 'YourContainerName';
this.storageKey = 'YourStorageAccountKet';
this.storageUrl ='https://YourStorageName.blob.core.windows.net';
this.blobName = '/'+storageName+'/'+storageContainer+'/'+fileName;
System.debug('blobName--->'+blobName);
this.requestURL = storageUrl+'/'+storageContainer+'/'+fileName;
System.debug('requestURL--->'+requestURL);
this.fileLength = String.valueof(intFileLength);
String strSharedKey = getBlobSharedKey();
try
{
this.uploadBlob(fileBody, strSharedKey);
isUploaded = true;
}catch(Exception exp)
{
System.debug('Exception occur while uploading the Blob-->'+exp.getMessage());
isUploaded = false;
}
return isUploaded;
}
public String getBlobSharedKey()
{
System.debug('getBlobSharedKey--->Start');
String sharedKey;
String signature;
Datetime dt = Datetime.now();
this.formattedDate = dt.formatGMT(DATEFORMAT);
String stringToSign = 'PUT\n\n\n'+fileLength+'\n\n'+fileType+'\n\n\n\n\n\n\nx-ms-blob-type:BlockBlob\nx-ms-date:'+formattedDate+'\nx-ms-version:2015-12-11\n'+blobName;
System.debug('stringToSign--->'+stringToSign);
Blob unicodeKey = EncodingUtil.base64Decode(storageKey);
Blob data = Crypto.generateMac('HMACSHA256', Blob.valueOf(stringToSign), unicodeKey);
signature = EncodingUtil.base64Encode(data);
sharedKey = 'SharedKey '+storageName+':' + signature;
return sharedKey;
}
public void uploadBlob(Blob fileBody, String sharedKey)
{
HttpRequest req = new HttpRequest();
req.setMethod('PUT');
req.setHeader('x-ms-blob-type', BLOB_TYPE);
req.setHeader('x-ms-version', VERSION);
req.setHeader('x-ms-date', formattedDate);
req.setHeader('Authorization', sharedKey);
req.setHeader('Content-Type', fileType);
req.setHeader('Content-Length', fileLength);
req.setEndpoint(this.requestURL);
req.setBodyAsBlob(fileBody);
Http http = new Http();
HTTPResponse res = http.send(req);
// in the response body you have your blob
System.debug('Response Body--->'+res.getBody());
System.debug('Status--->'+res.getStatus());
}
}
Я был бы рад, если бы кто-нибудь из этого поста переделал код более чистым способом.
Надеюсь, это вам пригодится, ребята
Спасибо, Зейн