简体   繁体   中英

Javascript: Sends two arrays of base64 encoded images to php via xhr

Hello everyone I'm here again. I'm trying to write a code that's able to resize all images before they're uploaded to the server. Once these images are in server-side, I need to know which array they belong to treat each one differently. For this purpose I'm using two arrays taht's get files from two inputs as shown in the code below:

HTML

<form method="post">
<input type="file" name="one[]" id="one" accept="image/jpeg, image/jpg" size="6" multiple/>
<input type="file" name="two[]" id="two" accept="image/jpeg, image/jpg" size="6" multiple/>
<button type="submit" id="submitButton">Submit</button>
</form>

JAVASCRIPT

var imgMaxWidth   = 1014; //Max width to resized image
var imgMaxHeight  = 1350; //Max height to resized images
var arrayOne = [];
var arrayTwo = [];
var arrayTest = ['zero', 'one', 'two'];

$(function() {
    var submitButton = $("#submitButton")
    /**
     * Resizes all images before upload
     * @param  {object?} input that contain images files
     * @param  {array} arrayIndex decides which array to push
     */
    var resizeBeforeUpload = function(input, arrayIndex) {
      // Checks has inputed files
      if (input.files) {
        // count files
        var filesAmount = input.files.length;
        // loop through files
        for (i = 0; i < filesAmount; i++) {
          // creates file reader object
          var reader = new FileReader();
          // awaits load end
          reader.onloadend = function(event) {
            var tempImg = new Image();
            tempImg.src = event.target.result;
            // execute when images load
            tempImg.onload = function() {
              // Assigns the variables according to previously defined limits
              var MAX_WIDTH = imgMaxWidth;    //imgMaxWidth  = 1014;
              var MAX_HEIGHT = imgMaxHeight; //imgMaxHeight  = 1350;
              var tempW = tempImg.width;
              var tempH = tempImg.height;
              // Handles de sizes correction
              if (tempW > tempH) // is width greater than height?
              { 
                if (tempW > MAX_WIDTH) { // is image.width greater than MAX_WIDTH variable?
                  // Image.height equals Image.height * MAX_WIDTH divided by image.width
                  tempH *= MAX_WIDTH / tempW;
                  tempW = MAX_WIDTH;
                }
              } else {
                if (tempH > MAX_HEIGHT) {
                  tempW *= MAX_HEIGHT / tempH;
                  tempH = MAX_HEIGHT;
                }
              }
              // Creates a canvas element
              var canvas = document.createElement('canvas');
              // Assigns width and height to canvas
              canvas.width = tempW;
              canvas.height = tempH;
              // Returns a bidimensional drawing context on canvas
              var ctx = canvas.getContext("2d");
              // Draw the image
              ctx.drawImage(this, 0, 0, tempW, tempH);
              /* Returns a base64 from the canvas, 
              [0.6] is a image quality indicator -> [from 0.1=low, to 1.0=high]*/
              var dataURL = canvas.toDataURL("image/jpeg", 0.6);
              // *** here starts the mess ***
              // I added the index checking to be able to separate arrays
              if (arrayIndex == 1) {
                // push this array
                arrayOne.push(dataURL);
              } else if (arrayIndex == 2) {
                // push this array
               arrayTwo.push(dataURL);
              }
            }
          }
          reader.readAsDataURL(input.files[i]);
        }
      }
    };
    // On click form submit button
    submitButton.unbind().click(function(e){
       $(this).prop("disabled", true);
      // prevent default submiting form
      e.preventDefault();
      // run resizeBeforeUpload(input, index=1);
      resizeBeforeUpload(document.getElementById('one'), 1)
      console.log(arrayOne);
      // run resizeBeforeUpload(input, index=2);
      resizeBeforeUpload(document.getElementById('two'), 2)
      console.log(arrayTwo);
      console.log(arrayTest);

      
    });
  });

But when I send the form by clicking its button, the data is sent incompletely. Sometimes I get all arrays with all images, but sometimes only some images are being uploaded. I believe this is happening because the form is being submitted before the entire array is filled. Could you help me resolve this issue? I need to get the list of images from each of the inputs, then I need each of these images reduced, then I need them to be uploaded to the server in base64 format. Something like this:

data = 'firstArray='+arrayOne+'&secondArray='+arrayTwo;
xhr.send(data);

With each of the arrays separate I'll be able to put each of them in different tables in the database:

[...]
$firstArray = $_POST[firstArray][i];
$secondArray = $_POST[secondArray][i];
[...]

Here's a fiddle example: link

Javascript doesn't wait for asynchronous functions. When resizeBeforeUpload is finished, reader.onloadend will not be executed yet. You should make resizeBeforeUpload function to return a promise .

In the submit function you should wait both to finish with Promise.all .

Your functions should look like below.

var imgMaxWidth   = 1014; //Max width to resized image
var imgMaxHeight  = 1350; //Max height to resized images
var arrayOne = [];
var arrayTwo = [];
var arrayTest = ['zero', 'one', 'two'];
$(function() {
    var submitButton = $("#submitButton")
    /**
     * Resizes all images before upload
     * @param  {object?} input thats contain images files
     * @param  {array} arrayIndex decides which array to push
     */
    var resizeBeforeUpload = function(file) {
        return new Promise(resolve => {
      
            // creates file reader object
            var reader = new FileReader();
            // awaits load end
            reader.onloadend = function(event) {
              var tempImg = new Image();
              tempImg.src = event.target.result;
              // execute when images load
              tempImg.onload = function() {
                // Assigns the variables according to previously defined limits
                var MAX_WIDTH = imgMaxWidth;    //imgMaxWidth  = 1014;
                var MAX_HEIGHT = imgMaxHeight; //imgMaxHeight  = 1350;
                var tempW = tempImg.width;
                var tempH = tempImg.height;
                // Handles de sizes correction
                if (tempW > tempH) // is width greater than height?
                { 
                  if (tempW > MAX_WIDTH) { // is image.width greater than MAX_WIDTH variable?
                    // Image.height equals Image.height * MAX_WIDTH divided by image.width
                    tempH *= MAX_WIDTH / tempW;
                    tempW = MAX_WIDTH;
                  }
                } else {
                  if (tempH > MAX_HEIGHT) {
                    tempW *= MAX_HEIGHT / tempH;
                    tempH = MAX_HEIGHT;
                  }
                }
                // Creates a canvas element
                var canvas = document.createElement('canvas');
                // Assigns width and height to canvas
                canvas.width = tempW;
                canvas.height = tempH;
                // Returns a bidimensional drawing context on canvas
                var ctx = canvas.getContext("2d");
                // Draw the image
                ctx.drawImage(this, 0, 0, tempW, tempH);
                /* Returns a base64 from the canvas, 
                [0.6] is a image quality indicator -> [from 0.1=low, to 1.0=high]*/
                var dataURL = canvas.toDataURL("image/jpeg", 0.6);
                resolve(dataURL);
              }
            }
            reader.readAsDataURL(file);
      });
    };
    
    var getFiles = (inputElement) => {
    
        const promiseArray = Array.from(inputElement.files).map(file => resizeBeforeUpload(file));
    
        return Promise.all(promiseArray);
    };
    
    // On click form submit button
    submitButton.unbind().click(function(e){
        $(this).prop("disabled", true);
      // prevent default submiting form
      e.preventDefault();
      Promise.all([
        getFiles(document.getElementById('one')),
        getFiles(document.getElementById('two')),
        ]).then(([oneResults, twoResults]) => {
        console.log(oneResults);
        console.log(twoResults);
      })
    });
});

Fiddle Link

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM