Richard Purnell
Richard Purnell

Reputation: 1

Occasionally uploading larger files

On moving to the next step in the form I have run some checks. One is to stop photos over 10mb and preventing .heic files from being upload. 90% of the time it works, but now and again files are let through.

Any help with a better written solution or a reason why this may fail and let large files or .heic file through.

var upload_one = document.getElementById("image_one");

            if(upload_one.files.length > 0) {
                    if (upload_one.files.item(0).size >= '10485760') {
                        upload_one.className += " invalid";
                        valid = false;
                        alert("Photo is too large. Photos need to be under 10mb")
                    }

                    fileName = document.querySelector('#image_one').value;
                    extension = fileName.split('.').pop();

                    if (extension == 'heic') {
                        upload_one.className += " invalid";
                        valid = false;
                        alert("Files can only be .png, .jpg or .jpeg")

                    }
                } 

Upvotes: 0

Views: 32

Answers (1)

Berthelot Loïc
Berthelot Loïc

Reputation: 31

You should have a look at presigned Url using S3 bucket on aws. Basically you generate an upload url where you can upload big files direclty to S3.

Personally I use a lambda to generate this presignedUrl and I return it to front end then.

Backend

const AWS = require("aws-sdk");
const S3 = new AWS.S3();
const { v4: uuidv4 } = require("uuid");


const getUrl = async (params) => {
  return await new Promise((resolve, reject) => {
    S3.getSignedUrl("putObject", params, (err, url) => {
      if (err) {
        reject(err);
      } else {
        resolve({
          statusCode: 200,
          url,
        });
      }
    });
  });
};

exports.handler = async (event, context) => {

  const id = uuidv4();
  const { userId } = event?.queryStringParameters;

  const params = {
    Bucket: process.env.INVOICE_BUCKET,
    Key: `${userId}/${id}.csv`,
    ContentType: `text/csv`,
    ACL: "public-read",
  };
  
  try {
    const { url } = await getUrl(params);
    return handleRes({ message: `Successfully generated url`, url, key: `${id}.csv`, publicUrl: `https://yourBucket.s3.eu-west-1.amazonaws.com/${userId}/${id}.csv` }, 200);
  } catch (e) {
    console.error(e);
    return handleRes({ message: "failed" }, 400);
  }
};

Front end

$(function () {
$("#theForm").on("submit", sendFile);
});



function sendFile(e) {
    e.preventDefault();
    var urlPresigned;
    var publicUrl;
    var key;
    $.ajax({
      type: "GET",
      url: `https://yourId.execute-api.eu-west-1.amazonaws.com/Prod/file-upload-to-bucket?userId=${userId}`,
      success: function (resp) {
        urlPresigned = resp.url;
        publicUrl = resp.publicUrl;
        key = resp.key;
        var theFormFile = $("#theFile").get()[0].files[0];

        $.ajax({
          type: "PUT",
          url: urlPresigned,
          contentType: "text/csv", // Put meme type
          processData: false,
          // the actual file is sent raw
          data: theFormFile,
          success: function () {

            // File uploaed
          },
          error: function (err) {
            console.log(err);
          },
        });
      },
    });
  }

Upvotes: 1

Related Questions