2

I have a variables src and image,

var src = $("#img_tag").attr('src');
var image = new Image();

I want to pass this image variable to a public function in php to upload. What is it that exactly that I need to pass, is it the src, the base64, the image itself as new FormData ?

Right now I have:

var data = new FormData();
var src = $("#img_tag").attr('src');
var image = new Image();
data.append('Image', image);

console.log(data);

$.ajax({  
    url: "/products/image_upload",  
    type: "POST",  
    data:  data,
    processData: false,  
    contentType: false, 
    success: function (msg) {
        console.log(msg+"---Image was uploaded");
    }
    error: function(err) {
        console.log(err);
    }
});

In my view:

public function image_upload() {
    $this->autoRender = false;
    echo json_encode($this->data);
    if($this->request->is('post'))
    {
         if(!empty($_FILES['Image']['name'])) {
            $file = $_FILES['Image'];
            echo json_encode($file);
            $ext = substr(strtolower(strrchr($file['name'], '.')), 1);
            $arr_ext = array('jpg', 'jpeg', 'gif', 'png');
            $temp = explode(".", $file['name']);
            $newfilename = $_FILES['Image']['name'];
            if(in_array($ext, $arr_ext))
            {
                if(move_uploaded_file($file['tmp_name'], WWW_ROOT . 'img/product-uploads' . DS . $newfilename))
                {
                    echo json_encode("Image uploaded properly");
                    return json_encode($_FILES);
                }
            }
        }
    }
}

And getting:

 {"Image":"[object HTMLImageElement]"}---Image was uploaded

BUT IMAGE IS NOT UPLOADED

Mae Cana
  • 43
  • 1
  • 10
  • 1
    You need to upload the binary data of the image, not the string representation of it. What exactly are you trying to do here? I believe this is an X/Y problem, as I don't believe your final goal is to upload an empty image. – Rory McCrossan Feb 13 '18 at 15:33
  • Have you tried this? `data.append('Image', src);` 2) Don't use `$_FILES` it will allways be empty, just use the JSON data. – odan Feb 13 '18 at 15:37
  • Oh, thank you for pointing that out, I've been pulling my hair out debugging this, all this time I'm passing an empty image, wait, let me try and pass the src to that image – Mae Cana Feb 13 '18 at 15:38
  • @DanielO, If I use the src will the image be moved to the directory ? – Mae Cana Feb 13 '18 at 15:39
  • No files will be uploaded or moved. Via Ajax it's only the "content" of the file (base64 encoded). – odan Feb 13 '18 at 15:42
  • 1
    More details: https://stackoverflow.com/questions/6974684/how-to-send-formdata-objects-with-ajax-requests-in-jquery – odan Feb 13 '18 at 15:47
  • Thank you for that, I'll study on how to get the content and upload it as image. – Mae Cana Feb 13 '18 at 15:49
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/165084/discussion-between-winter-cara-and-danielo). – Mae Cana Feb 13 '18 at 18:47

2 Answers2

1

If you take a look at the FormData.append doc, you will see that the second argument takes a string or a blob.
So passing an HTMLImageElement isn't going to work, if you cant get the image as a Blob or a File using a FormData object doesn't really help.
Since you're trying to upload the src of #img_tag, this will only really work if it is the base64 encoded image.
In this case use data.append('Image', src); and read the data from $_POST['Image'] then clean it up and decode it.

If the image src is a regular url, use $_POST['Image'] with curl to download the image to your server.

Musa
  • 96,336
  • 17
  • 118
  • 137
1

I got a bit of a research, and found this article super helpful. (Thanks to that)

I managed to upload an image file to a directory in my server from an image src by getting the base64 encoded image, passed for the controller to decode and upload. (Also thanks to Musa, DanielO, and Rory McCrossan)

In Controller: Code from this article. (I added a custom filename in a datetime format)

public function additional_image_upload() {
    $this->autoRender = false;

    $base64 = $this->request->data['base64'];
    $product_id = $this->request->data['id'];
    $baseFromJavascript = $base64;

    $data = base64_decode(preg_replace('#^data:image/\w+;base64,#i', '', $baseFromJavascript));

    $t = microtime(true);
    $micro = sprintf("%06d",($t - floor($t)) * 1000000);
    $date_tmp = new DateTime( date('Y-m-d H:i:s.'.$micro, $t) );

    $date = $date_tmp->format("Y-m-d_his.u");
    $filepath = WWW_ROOT . 'img/product-uploads' . DS ."$date.jpg"; // or image.jpg
    file_put_contents($filepath,$data);
}

In Script: (I passed the base64 encoded image for the controller to handle)

var src = $(this).attr('src');
$.ajax({
    url:"/products/additional_image_upload",
    data:{
        "id": "<?= $id; ?>",
        "base64": src
    },
    type:"POST",
    success: function(msg) {
        console.log(msg."---Img uploaded");
    },
    error: function(error) {
        console.log(error);
    }
});

And all was working great. Added this to help future readers.

Mae Cana
  • 43
  • 1
  • 10