19

I have a VF page that is used to load files to AWS. In the past the files were smaller and the 5M VF limit was fine. Now most of the files are larger than 5M and I can no longer upload them using this VF page.

What is the workaround or alternative?

2
  • What error are you getting? The maximum size for a file upload is documented as 10MB here, salesforce.com/us/developer/docs/pages/Content/… Commented Jan 29, 2013 at 16:52
  • Your right, I meant to write 10M (5M is the old limit). 10M is also too small for me. Any suggestion beside ajax toolkit?
    – Dedo
    Commented Jan 30, 2013 at 6:40

2 Answers 2

19

Use the ajax toolkit to perform the upload from javascript. This way you avoid apex heap size limit. I've done it and successfully uploaded files up to ~35 mb in size.

1) Reference the ajax toolkit in your visualforce page.

<apex:includeScript value="../../soap/ajax/26.0/connection.js" />

2) Write javascript to upload to server (in this case its as an attachment, but contents or documents should also work).

function uploadAttachment(filecontent, filename, filetype, parentId) {
    var attachment         = new sforce.SObject('Attachment');
    attachment.Name        = filename;
    attachment.IsPrivate   = false;
    attachment.ContentType = filetype;
    attachment.Body        = filecontent;
    attachment.Description = filename;
    attachment.ParentId    = parentId;
    sforce.connection.create([attachment]);
}

3) Write some js to get at file content. This is the only difficult step. You could use HTML5 file API but its support is limited. Ill do a drag-n-drop example as its more supported.

<script>
    var dropzone = document.getElementById('dropzone');
    dropzone.addEventListener("drop", drop, false);

    function drop(evt) {
        endEvent(evt);        
        var files = evt.originalEvent.dataTransfer.files;            
        if (files.length > 0) {
            try {
                uploadFiles(files); 
            } catch(error) {
                alert('An error occured in sfdc-dragndrop.js: ' + error);
            }  
        } 
    }

    function uploadFiles(files) {
        for(var index = 0, file; file = files[index]; index++) {
            var reader = new FileReader();

            reader.onloadend = 
                (function(file) { 
                     return function(evt) {
                         var fileContent = getFileContent(evt.target.result)
                         var parentId    = <id of attachment parent>;
                         uploadAttachment(fileContent, file.name, file.type, parentId);
                     };
                 })(file);

            reader.readAsDataURL(file);
        }
    }

    function getFileContent(fileData) {
        var fileContent = String(fileData);
        return fileContent.substr(fileContent.indexOf(',') + 1);
    }
</script>

Hopefully all that code works and gets you what you need (i dug it out of an old project and changed it a little on the fly to be stackexchange-friendly), if not it should be a step in the right direction.

4
  • Thanks. I'm not sure how to do it. Can you maybe share a code sample?
    – Dedo
    Commented Jan 30, 2013 at 6:42
  • can you share some sample of how to achieve this using the AJAX toolkit?
    – Dedo
    Commented Mar 4, 2013 at 12:04
  • Updated answer based on comments.
    – Phil Rymek
    Commented Mar 4, 2013 at 17:36
  • I don't think this works with Internet Explorer or Safari. FileReader is the problem.
    – Dave
    Commented Jan 27, 2015 at 20:02
3

Based the example above but using HTML5 and the Content Objects:

<apex:page >
    <script type="text/javascript">__sfdcSessionId = '{!$Api.Session_Id}';</script>
    <script src="../../soap/ajax/30.0/connection.js" type="text/javascript"></script>

    <script language="JavaScript">

        function uploadContentVersion(filename, filecontent) {
            var contentVersion          = new sforce.SObject('ContentVersion');
            contentVersion.pathOnClient = filename;
            // Set origin to 'C' if uploading to content 
            // and set the FirstPublishLocationId to either a UserId or ContentWorkspaceId
            contentVersion.origin       = 'H'; 
            contentVersion.VersionData  = filecontent;
            var results = sforce.connection.create([contentVersion]);
            for (var i = 0; i < results.length; i++) {
                if (results[i].getBoolean("success")) {
                    alert('New ContentVersion record created:' + results[i].id);
                }
                else {
                    alert('Failed:' + results[i]);

                }
            }
        }

        function fileSelected() {
            var file = document.getElementById('fileToUpload').files[0];
            if (file) {
                var fileSize = 0;
                if (file.size > (36 * 1024 * 1024)) {
                    alert('File too large, greater than 36MB');
                    return;
                }
                if (file.size > 1024 * 1024)
                    fileSize = (Math.round(file.size * 100 / (1024 * 1024)) / 100).toString() + 'MB';
                else
                    fileSize = (Math.round(file.size * 100 / 1024) / 100).toString() + 'KB';

                document.getElementById('fileName').innerHTML = 'Name: ' + file.name;
                document.getElementById('fileSize').innerHTML = 'Size: ' + fileSize;
                document.getElementById('fileType').innerHTML = 'Type: ' + file.type;
            }
        }

        function uploadFile() {
            var file = document.getElementById('fileToUpload').files[0];
            var reader = new FileReader();
            reader.onload = loaded;
            reader.onerror = errorHandler;
            reader.readAsDataURL(file);           
        }

        function loaded(evt) {
            var filename = document.getElementById('fileToUpload').files[0].name;
            var fileContent = String(evt.target.result);
            fileContent = fileContent.substr(fileContent.indexOf(',') + 1);
            uploadContentVersion(filename, fileContent);  
        }

        function errorHandler(evt) {
            if (evt.target.error.name == 'NotReadableError') {
                alert('File could not be read');
            }
            else {
                alert(evt.target.error);
            }
        }

</script>

    <title>Upload Files using XMLHttpRequest - Minimal</title>
    <form id="form1" enctype="multipart/form-data" method="post">
        <div class="row">
          <label for="fileToUpload">Select a File to Upload</label><br />
          <input type="file" name="fileToUpload" id="fileToUpload" onchange="fileSelected();"/>
        </div>
        <div id="fileName"></div>
        <div id="fileSize"></div>
        <div id="fileType"></div>
        <div class="row">
            <input type="button" onclick="uploadFile()" value="Upload" />
        </div>
  </form>
</apex:page>
1
  • Is the limit 36 MB or the API limit of 38 MB when uploading via the ajax toolkit ?
    – newbie
    Commented Aug 13, 2014 at 22:03

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .