4

I try to write script that send image data to controller and save it , I get the image with jQuery then create form data and send it with ajax but in controller my index is undefined , I try to save the image with $_FILES, my code is : my ajax script is :

var CSRF_TOKEN = $('meta[name="csrf-token"]').attr('content');
var title_image = $('#questionTitleImage').prop('files')[0];
var form_data = new FormData();
form_data.append('file', title_image);
$('#addQuestionLoader').show();
$.ajax({
    url: '/imageUpload/',
    type: 'GET',
    data: form_data,
    contentType: false,
    processData: false,
    success: function (data) {
        console.log(data);
    },
    complete:function () {
        $('#addQuestionLoader').hide();
    }
});

And my controller is :

public function imageUpload(Request $request) {
    if ( 0 < $_FILES['file']['error'] ) {
        echo 'Error: ' . $_FILES['file']['error'] . '<br>';
    } else {
        move_uploaded_file($_FILES['file']['tmp_name'], 'uploads/' . $_FILES['file']['name']);
    }
}

Please help me to complete my project , if you have best way to save image with ajax please help me.

4
  • do a var_dump on $_FILES paste it here Commented Dec 13, 2016 at 9:24
  • the result is null Commented Dec 13, 2016 at 9:35
  • note: this will not work in lower than ie10 ,how are you triggering the ajax event? Commented Dec 13, 2016 at 9:38
  • i just use chrome and firefox Commented Dec 13, 2016 at 10:12

1 Answer 1

1

I think you aren't sending the file to the server at all. I could be mistaken though, but you could try something like this:

var CSRF_TOKEN = $('meta[name="csrf-token"]').attr('content');
var title_image = $('#questionTitleImage').prop('files')[0];

var xhr = new XMLHttpRequest();
if (xhr.upload) {
    formData.append('file', title_image);
    // you forgot including the token
    formData.append('_token', CSRF_TOKEN);
    // change your request to POST, GET is not good for files
    xhr.open("POST", '/imageUpload', true);
    xhr.send(formData);

    xhr.onreadystatechange = function() {
        if (xhr.readyState == 4 && xhr.status == 200) {
            alert("Uploaded");
        }
    }
}

This is the javascript code I'm using to send an image file to the server.

As for the controller, the move_uploaded_file function you're using should be working fine, although I'm using Laravel's native file handling plus a library called Intervention image.

http://image.intervention.io/

Intervention image is great, you could do a whole lot with it, I recommend it!

Here's how I handle the image upload:

use Illuminate\Http\Request;
use Intervention\Image\ImageManager;

public function upload(Request $request)
{
    // get image
    $file = $request->file('file');

    // instantiate Intervention Image
    $imageManager = new ImageManager();
    $image = $imageManager->make($file);

    // save image with a new name
    $image->save(public_path() . '/img/new-image.jpg', 100);

    return response()->json([
        'success' => true,
    ]);
}

If you don't want to use intervention image, you could just transfer the file using Laravel's native file handler:

// get image
$file = $request->file('file');
// save it
$file->store('img');

Hope this helps, keep me posted with what's happening and I'll help :)

EDIT: Here's the full example

// javascript
$('body').on('change', '#questionTitleImage', function(e){
    e.stopPropagation();
    e.preventDefault();

    var CSRF_TOKEN = $('input[name=_token]').val();
    var files = e.target.files || e.dataTransfer.files;
    var file = files[0];

    var xhr = new XMLHttpRequest();
    if (xhr.upload) {
        var formData = new FormData();
        formData.append('file', file);
        formData.append('_token', CSRF_TOKEN);
        xhr.open("POST", '/image', true);
        xhr.send(formData);

        xhr.onreadystatechange = function() {
            if (xhr.readyState == 4 && xhr.status == 200) {
                alert('Success');
            }
        }
    }
});

CSRF Token field:

// this goes below your input type file
{{ csrf_field() }}

And afterwards, append it to the formdata like this:

formData.append('_token', $('input[name=_token]').val());
Sign up to request clarification or add additional context in comments.

10 Comments

thanks for your answer , i follow your answer and do all things you said but $request->file('file') is still return null :( , why?
Okay, a couple of question - #questionTitleImage is an <input type="file">, correct? Afterwards, on sending the request - could you console.log(title_image) and see if title_image returns a file - it could be that the javascript doesn't return a file instance at all. If it doesn't, I'll write down the whole code.
#questionTitleImage is file input yes! ,and the title_imgae before send is : File {name: "Chrysanthemum.jpg", lastModified: 1247549551674, lastModifiedDate: Tue Jul 14 2009 10:02:31 GMT+0430 (Iran Daylight Time), webkitRelativePath: "", size: 879394…}
i forget to say just one thing , when i follow your answer first i get this error from laravel : image source not readable , second i var_dump the request in controller and i find out my request is empty
I edited my answer to include the full example after EDIT:, let's try that one.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.