0

I've got a FileReader that lets the user upload a file (image) to my site.

Here's the code that does the reading:

$("input[type='file']").change(function(e) {

    var buttonClicked = $(this);

    for (var i = 0; i < e.originalEvent.srcElement.files.length; i++) {

        var file = e.originalEvent.srcElement.files[i];

        var img = document.createElement("img");
        var reader = new FileReader();
        reader.onloadend = function() {
            img.src = reader.result;                

            console.log(reader.result);

        }
        reader.readAsDataURL(file);
    }
});

All is good and well, until I tried to print out my result. I used this file for example: enter image description here

When I console.log() the result, it spits out over 95000 characters.

This image in particular is around the same size as the images I will be accepting into my site.

I was hoping to store these images in a database as well, and so I'm wondering how this is going to be possible with image sources that are so extremely long. Is there a way to shorten this or get the image path a different way?

I'm moreso curious as to why they're so long, but if someone has a tip to store these (100s per user, 500+ users) that'd be nice as well!

Thanks-

follmer
  • 1,050
  • 3
  • 14
  • 31

2 Answers2

1

Store the Files as ... Files.

There are very little use cases where you need the toDataURL() method of the FileReader, so every time you use it, you should ask yourself why you need it.

In your case :

  • To display the image in the page. Well don't use a FileReader for this, instead create a direct pointer to the file in the form of an url, available only to this session. This can be achieved with the URL.createObjectURL(File_orBlob) method.
  • To store this image on your server. Don't store a ~37% bigger base64 version, send and store directly the file as a file (multipart). This can be achieved easily with the FormData API.

inp.onchange = function(){
  var file = this.files[0];
  if(file.type.indexOf('image/') !== 0){
    console.warn('not an image');
    }
  var img = new Image();
  img.src = URL.createObjectURL(file);
  // this is not needed in this case but still a good habit
  img.onload = function(){
    URL.revokeObjectURL(this.src);
    };
  document.body.appendChild(img);
  }

// not active but to give you da codez
function sendToServer(){
  var file = inp.files[0];
  var form = new FormData();
  // here 'image' is the parameter name where you'll retrieve the file from in the request
  form.append('image', file); 
  form.append('otherInfo', 'some other infos');
  var xhr = new XMLHttpRequest();
  xhr.open('post', 'yourServer/uploadPage')
  xhr.onload = function(){
    console.log('saved');
    };
  xhr.send(form);
  }
<input type="file" id="inp">

And if you need PHP code to retrieve the File form this request :

if ( isset( $_FILES["image"] ) ){
  $dir = 'some/dir/';
  $blob = file_get_contents($_FILES["image"]['tmp_name']);
  file_put_contents($dir.$_FILES["image"]["name"], $blob);
}
Community
  • 1
  • 1
Kaiido
  • 123,334
  • 13
  • 219
  • 285
  • Great, I will give this a try when I get a chance, that makes much more sense. Thank you. – follmer May 11 '17 at 04:12
  • This works well, however, I am trying to save this url client-side but it is a blob where its lifetime is just the session. Is there any other ways that produces a short path that isn't a blob and can be stored? Or even a blob storage? – Sean May 09 '20 at 05:30
  • 1
    @Sean yes IndexedDb can store binary files in the client's HDD. – Kaiido May 10 '20 at 23:51
  • @Kaiido Perfect! Thank you very much – Sean May 11 '20 at 00:17
0

You're going to want to upload the files to a server of some sort (a backend that is serving up your javascript), and then from there you'll want to

  1. Validate the file
  2. Store the file on a physical server (or the cloud) somewhere
  3. Add an entry in a database that relates the file path or ID of that upload to the user who just uploaded it (so you can retrieve it later if needed)

So basically, you don't store the image in your database, you store it on a file share/cloud host somewhere, and instead you only store what is needed to download/retrieve the image later.

mariocatch
  • 8,305
  • 8
  • 50
  • 71
  • Is this possible through a host? i.e. if my site was hosted through godaddy/namecheap etc, is this still possible? – follmer May 11 '17 at 04:01
  • So those two examples are just domain name providers. For hosting your website you'll need a web host. You can (and should) get all of this working locally first before buying anything. You'll need a backend technology (ASP, PHP, Node, Python, Ruby, etc...), and then you'll need to send the request from your javascript to the server, and the server will process it and do what's needed. – mariocatch May 11 '17 at 04:03
  • Sorry I misunderstood originally. I've already got the host, and I'm working with PHP. I think I'm a little confused as what you mean by "send the request from your javascript to the server". I already deal with plenty of POST requests, so I'm unsure how dealing with these images differs/works. Sorry if I'm missing the point, haven't dealt with user uploads before! – follmer May 11 '17 at 04:06
  • What @Kaiido answered is one way you can send the images to your server. In his use case you create a `FormData` javascript object, append your file to it, and then upload that to your server What you'll need to do is handle that on the server and do the things I listed in my answer. – mariocatch May 11 '17 at 04:08
  • Great, I think I understand now. Appreciate the help! – follmer May 11 '17 at 04:09