[SalesForce] Read a parameter passed via a form post with RequestParameter

I am trying to pass a base64 string via form parameters and read it with the RequestParameter AMPScript function. The thing is, the value returned by this AMPScript function is Empty – SET @b64file = RequestParameter("b64file")

Quick background: I use a Landing page that contains a Smart Capture form with the Email field (which relates to the Email field in the linked data extension). Also there is an control that allows the user to select an image file. Basically, when the user fills in the Email field, chooses a file and clicks submit, this data need to be transferred to SFMC.

HTML code of the landing page:

<div id="output"></div>
<form action="%%= RequestParameter('PAGEURL') =%%" method="POST" onsubmit="return validate()" enctype="multipart/form-data">

    <script type="text/javascript">
        var formData = new FormData(document.forms[0]);
        function validate() {

            return true;
        }

        function getBase64(file) {
            var reader = new FileReader();
            reader.readAsDataURL(file);
            reader.onload = function () {
                console.log(reader.result);
                document.getElementById("output").innerHTML = reader.result
                formData.append("b64file",  reader.result);
            };

            reader.onerror = function (error) {
                console.log('Error: ', error);
            };
        }

        function check() {

            try {
                var files = document.getElementById('files').files; // FileList object
                var file = files[0];
                getBase64(file); // prints the base64 string
            } catch(e) {
                alert('Error ' + e.name + ":" + e.message + "\n" + e.stack);
            }
            alert(formData.get("b64file"));
        }

        </script>

    <div>
        <center>
        <div>
            <div>
                <b>EMAIL</b>
            </div>
            <div>
                <input type="text" maxlength="254" name="Email" id="Email" value="" size="75"/>
            </div>
        </div>    
        <br />        
        <div>
            <p>Upload your photo</p>
            <p><input type="file" name="files" id="files" accept="image/png,image/jpeg"/></p>
        </div>
        <br />  
        <div>
            <input type="submit" value="Register"/>
            <br/>
        </div>

        <br/>
        <input type="button" value="check" onclick="check()"/>

        </center>
    </div>
    <!-- AMP Processing Placeholder DO NOT REMOVE -->
    <input type="hidden" name="__successPage" id="__successPage" value="http://pages.email...com/sandbox-photo-contest-status?type=success" />
    <input type="hidden" name="__errorPage" id="__errorPage" value="http://pages.email...com/sandbox-photo-contest-status?type=error" />
    <input type="hidden" name="__contextName" id="__contextName" value="FormPost" />
    <input type="hidden" name="__executionContext" id="__executionContext" value="Post" />
</form>

AMPScript code on the Processing tab of the Smart Capture form (I skipped the part where data is added to a data extension):

%[
/* Upload an Image with REST API call*/

VAR @auth, @url, @returnCode, @response, @regex, @accessToken

SET @auth = '{"clientId":"myclientId","clientSecret":"myclientSecret"}'
SET @url = "https://auth.exacttargetapis.com/v1/requestToken"
SET @returnCode = HTTPPost(@url, "application/json", @auth, @response)
/* OutputLine(Concat("<br>returnCode:", @returnCode)) */

IF @returnCode ==  200 THEN
    SET @regex = "^{.accessToken.:.(.*).,.*$"
    SET @accessToken = RegExMatch(@response, @regex, 1)
    /* RaiseError(Concat("returnCode: ", @returnCode, " response: ", @response, " accessToken: ", @accessToken))
     OutputLine(Concat("<br>accessToken:", @accessToken)) */

    SET @url = "https://www.exacttargetapis.com/asset/v1/content/assets/?access_token="
    SET @url = Concat(@url, @accessToken)
    SET @b64file = RequestParameter("b64file")

  /*
  RaiseError(Concat("b64file: ", Empty(@b64file)))
        RaiseError(Concat("b64file: ", Substring(@b64file, 1, 10)))

   SET @urlText = '{"name":"1px transparent gif asset2","assetType":{"name":"gif","id": 20},"file":"R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"}' 
    */
    SET @urlText = Concat('{"name":"1px transparent gif asset4","assetType":{"name":"gif","id": 20},"file":"', @b64file, '"}')

    SET @returnCode = HTTPPost(@url, "application/json", @urlText, @response)
    RaiseError(Concat("returnCode: ", @returnCode, " response: ", @response))
ENDIF
]%

UPDATED HTML:

<form action="%%= RequestParameter('PAGEURL') =%%" method="POST" onsubmit="return validate()" enctype="multipart/form-data">

    <script type="text/javascript">
        var formData = new FormData(document.forms[0]);
        function validate() {            
            return true;
        }

        function getBase64(file) {
            var reader = new FileReader();
            reader.readAsDataURL(file);
            reader.onload = function () {
                console.log(reader.result);
                //document.getElementById("output").innerHTML = reader.result
                //formData.append("b64file",  reader.result);
                var res = reader.result;
                var charIndx = res.indexOf(",");
                res = res.substr(charIndx+1);
                document.getElementById("b64file").setAttribute("value",  res);
            };

            reader.onerror = function (error) {
                console.log('Error: ', error);
            };
        }

        function dataURItoBlob(dataURI) {
            // convert base64/URLEncoded data component to raw binary data held in a string
            var byteString;
            if (dataURI.split(',')[0].indexOf('base64') >= 0)
                byteString = atob(dataURI.split(',')[1]);
            else
                byteString = unescape(dataURI.split(',')[1]);

            // separate out the mime component
            var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0];

            // write the bytes of the string to a typed array
            var ia = new Uint8Array(byteString.length);
            for (var i = 0; i < byteString.length; i++) {
                ia[i] = byteString.charCodeAt(i);
            }

            return new Blob([ia], {type:mimeString});
        }

        function check() {

            try {
                var files = document.getElementById('files').files; // FileList object
                var file = files[0];
                getBase64(file); // prints the base64 string
            } catch(e) {
                alert('Error ' + e.name + ":" + e.message + "\n" + e.stack);
            }
            alert(formData.get("b64file"));
        }

        </script>

    <div>
        <center>
        <div>
            <div>
                <b>EMAIL</b>
            </div>
            <div>
                <input type="text" maxlength="254" name="Email" id="Email" value="" size="75"/>
            </div>
        </div>    
        <br />        
        <div>
            <p>Upload your photo</p>
            <p><input type="file" name="files" id="files" accept="image/png,image/jpeg"/></p>
        </div>
        <br />  
        <div>
            <input type="submit" value="Register"/>
            <br/>
        </div>

        <br/>
        <input type="button" value="check" onclick="check()"/>

        </center>
    </div>
    <!-- AMP Processing Placeholder DO NOT REMOVE -->
    <input type="hidden" name="__successPage" id="__successPage" value="http://pages.email.ab-inbev.com/sandbox-photo-contest-status?type=success" />
    <input type="hidden" name="__errorPage" id="__errorPage" value="http://pages.email.ab-inbev.com/sandbox-photo-contest-status?type=error" />
    <input type="hidden" name="__contextName" id="__contextName" value="FormPost" />
    <input type="hidden" name="__executionContext" id="__executionContext" value="Post" />
    <input type="hidden" name="b64file" id="b64file" />
</form>

Best Answer

I found the problem. It's in FormData that needs to be posted in a separate XMLHttpRequest send(). But it's not a way for this case as I need to post once to the same page making form's parameters available for AMPScript. I changed the js code so it stores the base64 string in a hidden field. Now the RequestParameter function works.